一、常用概念与注解整理
1.1 概念
1、POJO 是 Plain Old Java Object(简单老式Java对象)的缩写。它是指在Java开发中普通的Java对象,不依赖于特定的框架或技术。POJO 类型通常用于表示领域模型、数据传输对象(DTO)或实体对象等。
1.2 注解
二、SpringMVC简介
1.1 SpringMVC概述
SpringMVC用于表现层开发,与Servlet相似,但使用上比Servlet更加简便。
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架。
1.2 入门案例
先创建项目:
下面是依赖的骨架:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>springMVC_01_quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
</dependencies>
</project>
如果缺少java文件按如下方式添加:
步骤1:使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>springmvc_01_quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
步骤2:创建SpringMVC控制器类(等同于Servlet功能)
第1步:声明Spring的Bean,用@Controller
第2步:设置当前操作的访问路径,用@RequestMapping("/地址")
第3步:设置当前操作的返回值类型,用@ResponseBody
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'springmvc'}";
}
}
步骤3:初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean。
//3.创建springmvc的配置文件,加载controller对应的bean
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
步骤4:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求。
createServletApplicationContext()方法:加载springmvc配置类,产生springmvc容器(加载springMVC容器配置)。
getServletMappings()方法:设置哪些请求归属springMVC处理(设置由springmvc控制器处理的请求映射路径)
createRootApplicationContext()方法:加载spring容器配置。
//定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"}; //所有请求归springMVC管理
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
1.3 入门案例工作流程分析
启动服务器初始化过程:
1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器。
2. 执行createServletApplicationContext方法,创建了webApplicationContext对象。
3. 加载SpringMvcConfig
4. 执行@ComponentScan加载对应的bean
5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法。
6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC
单次请求过程:
1. 发送请求localhost/save
2. web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
3. 解析请求路径/save
4. 由/save匹配执行对应的方法save()
5. 执行save()
6. 检测到有@ResponseBody直接将save()方法的返回值作为相应请求体返回给请求方。
1.4 Controller加载控制
因为功能不同,如何避免Spring错误的加载到SpringMVC的bean——加载Spring控制的bean的时候排除掉SpringMVC控制的bean。
方式1:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包。
方式2:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean。
excludeFilters()是设定排除的过滤器
includeFilters()是设定包含的过滤器
FilterType.ANNOTATION 按注解过滤
FilterType.REGEX 按正则过滤
type是指定类别,classes是指定具体项,二者都要。
@Configuration
@ComponentScan(value="com.itheima", //去扫路径下所有东西
excludeFilters=@ComponentScan.Filter( //排除掉一些
type = FilterType.ANNOTATION, //按照注解排除
classes = Controller.class //如果使用注解则排除
)
)
public class SpringConfig {
}
方式3: 不区分Spring与SpringMVC的环境,加载到同一个环境中。
//定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersinitConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"}; //所有请求归springMVC管理
}
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class); //将上面的复制下来,将Mvc删除
return ctx;
}
}
超级简化版本:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class}; //填写,自动配置
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class}; //填写
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"}; //填写
}
}
1.5 PostMan
简介:PostMan是一款功能强大的网页提奥什与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试。
特征:简单、实用、美观、大方
先点击左侧workspace,创建工作空间
三、请求与响应
2.1 请求映射路径
@RequestMapping可以加在类上面,代表整个这么模块的访问前缀:
2.2 GET请求与POST请求与中文乱码问题
Get请求的参数在请求头后面,以?开头,用&号连接参数:
http://localhost:8080/commonParam?name=100&age=15
需要写两个参数名作为传入参数:
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,Integer age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
发送POST请求,不仅可以发表单还可以发文件:
发送中文先前版本会乱码,处理方法是设置过滤器:
@Override
protected Filter[] getServletFilters(){
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
2.3 参数种类
1. 普通参数
如果传入参数的名字和GET请求的参数名字不同,不能实现映射.
可以通过@RequestParam("请求参数名")写在被赋值参数前面。
如:@RequestParam("请求参数名") 参数类型 被赋值参数
2.POJO类型参数
POJO类型,比如User类中含有String类型的参数name和int类型的参数age。
如果对应的属性名一致,可以自动将内容进行转化,直接塞入进去。
3.嵌套POJO类型参数
意思是在POJO类型里又加入一个引用类型,比如Address类型的address参数,其中Address是一个类,里面包含有String类型的province参数和String类型的city参数。
4.数组类型参数
像下面likes是一个String[]数组,想要传参:
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
将所有的key值写成一样的:
5.集合类型参数
它会尝试造一个对象,所以要加一个注解@RequestPARAM:
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
2.4 json数据传递参数
第1步:传入参数:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
第2步:在Body里选择raw然后选择JSON:
第3步:要在SpringMVC的配置文件中加上下面这句话,开启json数据转换为对象的功能:
第4步:加上@RequestBody
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
如果发送的POJO类型的json数据按照如下方式书写:
带有引用类型的书写方式如下:
2.5 日期型参数传递
//日期参数
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
2.6 响应
2.6.1 响应页面/跳转页面
只需要return页面即可:
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
2.6.2 响应文本数据
按照下面方式写会报错,因为会认为response text是一个页面:
所以要加上下面的注解:@ResponseBody
2.6.3 响应pojo数据
返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");user.setAge(15);
return user;
}
该注解可以激活类型的自动转换
四、REST风格
REST(Representational State Transfer)表现形式状态转换:访问网络资源的格式。
RESTful:根据REST风格对资源进行访问。
优点:书写简化+隐藏资源的访问行为
问题:如何区分不同的操作?是通过后面的提交方式进行区分:
GET(查询),POST(新增),PUT(修改),DELETE(删除)是常用的。
4.1 入门案例
设置当前请求方法为POST,表示REST风格中的添加操作:
用@RequestMapping标签的value设置访问路径,method设置访问方法。
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符(/{id}),并且占位符名称与方法形参名称相同:
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
当参数较少只有1个左右可以采用@PathVariable接收,当有多个参数用json格式数据接收:
4.2 入门案例优化
1. @RequestMapping(value = "/users")因为value都是以"/users"开头,因此可以用注解@RequestMapping("/books")提到类的外面。
2. @ResponseBody也可以提到类的外面。
3. 其中@ResponseBody和@Controller可以合并为@RestController注解。
4. @RequestMapping(method = RequestMethod.POST)可以直接被@PostMapping替换。
5. @RequestMapping(value="/{id}",method=RequestMethod.DELETE)可以被@DeleteMapping("/{id}")注解。
//@Controller
//@ResponseBody配置在类上可以简化配置,表示设置当前每个方法的返回值都作为响应体
//@ResponseBody
@RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
@RequestMapping("/books")
public class BookController {
// @RequestMapping( method = RequestMethod.POST)
@PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
// @RequestMapping(method = RequestMethod.PUT)
@PutMapping //使用@PutMapping简化Put请求方法对应的映射配置
public String update(@RequestBody Book book){
System.out.println("book update..."+book);
return "{'module':'book update'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
@GetMapping("/{id}") //使用@GetMapping简化GET请求方法对应的映射配置
public String getById(@PathVariable Integer id){
System.out.println("book getById..."+id);
return "{'module':'book getById'}";
}
// @RequestMapping(method = RequestMethod.GET)
@GetMapping //使用@GetMapping简化GET请求方法对应的映射配置
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
4.3 案例
4.3.1 环境配置
web的项目都需要如下ServletContainersInitConfig类:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
SpringMvcConfig也一定要配置,记得要加上@EnableWebMvc
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
静态资源不需要过MVC,可以在config目录下,创建一个SpringMvcSupport文件,然后重写其中的addResourceHandlers方法,可以放行一些文件。
可以调用registry下面的addResourceHandler方法,里面写的是当访问到某个目录下的所有文件时,然后设定放行...用.addResourceLocations方法,在里面写要放行的内容。
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/???时候,走/pages目录下的内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
}
}
然后要在SpringMvcConfig中把这个配置扫进去,加上:
@ComponentScan({"com.itheima.controller","com.itheima.config"})
下面实现基于RESTful页面数据交互的功能:
//添加
saveBook () {
axios.post("/books",this.formData).then((res)=>{
});
},
//主页列表查询
getAll() {
axios.get("/books").then((res)=>{
this.dataList = res.data;
});
}
五、SSM整合
5.1 SSM整合
在java目录下要创建config、controller、dao、domain、service这五个目录,其中在service下还要创建一个Impl包。
5.1.1 config包
——创建SpringConfig类,添加如下4个注解:
@Configuration //设置为配置类
@ComponentScan({"com.itheima.service"})
@PropertySource("jdbc.properties") //加载属性
@Import({JdbcConfig.class,MyBatisConfig.class})
——创建MyBatisConfig类,主要是数据源:
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
//dataSource是在容器中,Spring根据类型自动装配的
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); //创建factoryBean对象
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.itheima.domain");
return factoryBean;
}
//扫描映射,dao包
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
——创建JdbcConfig类:
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
——创建ServletConfig类:
继承AbstractAnnotationConfigDispatcherServletInitializer直接指定配置类
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//Web容器配置类
}
——创建SpringMvcConfig类:
@Configuration //Spring的核心配置类
@ComponentScan("com.itheima.controller") //扫包
@EnableWebMvc
public class SpringMvcConfig {
}
5.1.2 resources
——创建jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3606/ssm_db
jdbc.username=root
jdbc.password=111111
5.2 功能模块
5.2.1 造表和实体类
5.2.2 controller包
创建BookController类:
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public boolean save(@RequestBody Book book) {
return bookService.save(book);
}
@PutMapping
public boolean update(@RequestBody Book book) {
return bookService.update(book);
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Integer id) {
return bookService.delete(id);
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id) {
return bookService.getById(id);
}
@GetMapping
public List<Book> getAll() {
return bookService.getAll();
}
}
5.2.3 dao包
创建接口BookDao:
public interface BookDao {
//#{}里的内容是book里的属性
//tbl_book(type,name,description)是表里的字段名
//@Insert("inset into tbl_book values(null,#{type},#{name},#{description})")
@Insert("inset into tbl_book(type,name,description) values(#{type},#{name},#{description})")
public void save(Book book);
@Update("update tbl_book set type=#{type},name=#{name},description=#{description} where id=#{id}")
public void update(Book book);
@Delete("delete from tbl_book where id=#{id}")
public void delete(Integer id);
@Select("select * from tbl_book where id=#{id} ")
public Book getById(Integer id);
@Select("select * from tbl_book ")
public List<Book> getAll();
}
5.2.4 domain包
在domain里创建Book类,用于存储数据库中对应的属性变量,设置get和set方法以及toString方法。
5.2.5 service包
创建接口BookService,增删改操作一律返回boolean,true表示成功,false表示失败:
public interface BookService {
public boolean save(Book book); //保存
public boolean update(Book book); //修改
public boolean delete(Integer id); //按id删除
public Book getById(Integer id); //按id查询
public List<Book> getAll(); //查询全部
}
在impl目录下创建BookServiceImpl实现类,继承BookService接口:
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public boolean save(Book book) {
bookDao.save(book);
return true;
}
public boolean update(Book book) {
bookDao.update(book);
return true;
}
public boolean delete(Integer id) {
bookDao.delete(id);
return true;
}
public Book getById(Integer id) {
return bookDao.getById(id);
}
public List<Book> getAll() {
return bookDao.getAll();
}
}
5.2.6测试
测试业务层接口:
Controller测试:
5.2.7 开启事务
添加注解@EnableTransactionManagement:
在JdbcConfig里添加如下语句:
在BookService接口里添加@Transactional注解,表示开启事务。
下面是pom.xml全部内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>springmvc_08_ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
</plugins>
</build>
</project>
5.3 表现层数据封装
新的问题是,数据的格式种类太多样。于是我们创建了一个结果模型类,将数据封装到data属性中:
接下来的问题是,新增、修改和删除返回的都是true,那么我们怎么知道是进行的什么操作,于是便增加了一个字段code,比如20031表示新增,20041表示查询..:
又出现了一个问题,如果没有查询到数据返回了null,请问要如何得知?于是我们规定以0结尾表示查询失败,以1结尾表示查询成功:
最后考虑加入我们查询失败要返回什么呢?于是我们封装进了一条特殊消息message(msg)。
返回结果是Result,通过重载函数对Result进行赋值:
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag = bookService.delete(id);
return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
Book book= bookService.getById(id);
Integer code = book !=null ? Code.GET_OK:Code.GET_ERR;
String msg = book != null ? "":"数据查询失败,请重试!";
return new Result(code,book,msg);
}
@GetMapping
public Result getAll() {
List<Book> bookList= bookService.getAll();
Integer code = bookList !=null ? Code.GET_OK:Code.GET_ERR;
String msg = bookList != null ? "":"数据查询失败,请重试!";
return new Result(code,bookList,msg);
}
}
5.4 异常处理器
异常处理器:集中的、统一的处理项目中出现的异常。
1.异常要进行分类处理。2.异常要放到表现层处理。3.异常要用AOP思想处理。
在controller目录下创建ProjectExceptionAdvice,写入如下代码:
@RestControllerAdvice //开启异常处理
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class) //处理Exception异常
public Result doException(Exception ex) {
System.out.println("嘿嘿,异常你哪里跑!"); //打印在后台
return new Result(666,null,"嘿嘿,异常你哪里跑!"); //打印在前端页面
}
}
5.5 项目异常处理方案
第1步:搭建实验环境
在java目录下新建exception目录,然后创建2个类,BusinessException和SystemException:
在每个类中创建Integer类型的code变量,设置set和get方法,然后为每个类设置构造方法,分别是2个参数和3个参数:
第2步:模拟异常
下面是模拟查询是的异常:
下面是定义的报错编码:
下面是异常处理器的代码,在异常处理器中进行分门别类的处理:
5.6 案例:SSM整个标准开发
首先要将准备好的前端文件导入,同时要放行这几个文件,在controller目录下避免被过滤拦截:
让SpringMvc扫描到:
5.6.1 列表功能
在books.html也米娜编写ajax语句,用axios进行异步提交:
出现如下页面即为成功:
5.6.2 添加功能
首先让弹出窗口可见:
然后发送ajax请求,输入完数据后先让弹窗关闭,然后重新调用显示刷新:
分情况给出不同的提示信息:
5.6.3 修改功能
核心是加载回显数据,修改数据是在添加数据基础上变化。
在books.html中加入如下代码,then的后面返回的是结果:
//弹出编辑窗口
handleUpdate(row) {
//查询数据,根据id查询
axios.get("/books/"+row.id).then((res)=>{
if(res.data.code==20041){
this.formData = res.data.data; //数据回显
this.dialogFormVisible4Edit = true;//展示弹层,加载数据
}else{ //不成功
this.$message.error(res.data.msg); //弹出消息
}
})
},
在books.html中加入如下代码:
//修改
handleEdit() {//发送ajax请求
axios.put("/books",this.formData).then((res)=>{
if(res.data.code == 20031) {//成功
this.dialogFormVisible4Edit = false;//如果操作成功,关闭弹层
this.$message.success("修改成功");
}else if(res.data.code == 20030) {//失败
this.$message.error("修改失败");
}else{ this.$message.error(res.data.msg); }
this.getAll();
}).finally(()=>{
this.getAll();
})
},
5.6.4 删除功能
在books.html页面中写入如下代码:
// 删除
handleDelete(row) {
//1.弹出提示框
this.$confirm("此操作永久删除当前数据,是否继续","提示",{
type:'info'
}).then(()=>{//2.做删除业务
axios.delete("/books/"+row.id).then((res)=> {
if (res.data.code == 20021) {
this.$message.success("删除成功");
} else {
this.$message.error("删除失败");
}
}).finally(()=>{
this.getAll();
});
}).catch(()=>{
this.$message.info("已取消删除"); //3.取消删除
}).finally(()=>{
this.getAll();
});
}
六、拦截器
拦截器(Interceptor):是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。是一种工作机制,用于增强,可以在前或者后执行。
作用:1. 在指定的方法调用前后执行预先设定的代码。2.阻止原始方法的执行。
拦截器和过滤器的区别:
6.2 入门案例
在controller下创建一个interceotor目录表示拦截器:
第1步:声明拦截器的bean,并实现HandlerInterceptor接口(注意:要扫描加载bean)
第2步:定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法。在SpringMvcSupport里进行拦截器的配置:
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired //拦截器对象在容器里要注入
private ProjectInterceptor projectInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {//配置拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
}
}
记得要加@Configuration
还要记得加载配置类:
preHandle在原始被拦截之前运行的代码。
postHandle在拦截的原始操作之后运行的代码。
afterCompletion在拦截的原始操作之后运行的代码且在Post后面。
第3步:添加拦截器并且设定拦截的访问路径,路径可以通过可变参数设置多个。在SpringMvcSupport后面,修改addPathPatterns加入/books/*可以拦截带参数的:
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*"); //配置拦截器
}
false可以终止原始操作的执行,返回值类型可以拦截控制的执行,true放行,false终止。
注意:可以进行简化可以将SpringMvcSupport的内容直接防止在SpringMvcConfig中。
缺点:侵入性较强,程序与SpingMvc进行了强绑定。
6.3 拦截器工作流程分析
注意输出顺序,先执行2,后执行1,然后先执行1,再执行2,类似于堆栈。
假如现在在ProjectInterceptor2里return false则后面的流程都不会执行:
pre3返回false,执行after2后面,pre2返回false,执行after1后面:文章来源:https://www.toymoban.com/news/detail-660056.html
文章来源地址https://www.toymoban.com/news/detail-660056.html
到了这里,关于Spring学习笔记+SpringMvc+SpringBoot学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!