一.什么是SpringMVC
1.概念:SpringMVC是spring提供的一个较为便捷的web框架。由处理器映射、处理器(控制器)、 DispatcherServlet、视图解析器、视图组成。
2.运行视图:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象Handler及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter(让Handler实现更加灵活)处理器适配器调用处理器
5、执行处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView(连接业务逻辑层和展示层的桥梁,持有一个ModelMap对象和一个View对象)。
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet对View进行渲染视图(将ModelMap模型数据填充至视图中)。
11、DispatcherServlet响应用户
二.SpringMvc演示
一.pom依赖
<!--添加Tomcat依赖-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
<!--springmvc依赖-->
<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.2.10.RELEASE</version>
</dependency>
<!--json依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
项目结构,这里代码演示Controller层重点
二.spring配置
一.SpringMVC配置类
springmvc使用的Jackson,为了可以做到在controller层接收浏览器发来的json格式的数据,并转化成对象,需要再SpringMVC配置类中开启json数据转化。
@Configuration
//扫描controller包和SpringMVCSupport
@ComponentScan({"com.dengzhihong.controller","com.dengzhihong.config"})
//开启json数据转换
@EnableWebMvc
public class SpringMVC_Config {
}
二.Spring配置类
spring容器扫描除controller层的包有两种方式。
@Configuration
//设置除Controller包外的扫描,的两种方式
//@ComponentScan({"com.dengzhihong.dao","com.dengzhihong.pojo","com.dengzhihong.service"})
@ComponentScan(value = "com.dengzhihong",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class))
public class Spring_config {
}
三.SpringMVC容器配置类
(1).通过继承AbstractAnnotationConfigDispatcherServletInitializer
public class ServletContainnerInit_Config extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{Spring_config.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVC_Config.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 解决post乱码
* @return
*/
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
(2).SpringMVC容器继承AbstractDispatcherServletInitializer实现,不过较为麻烦,不推荐,两种方式是一样的,是父子类关系。
演示:
public class ServletContainnerInit_Config extends AbstractDispatcherServletInitializer{
/* *
* //加载springmvc配置类,生产springmvc容器
* @return
*/
@Override
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplication对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMVC_Config.class);
return ctx;
}
/**
* 设置由springmvc控制器处理的请求映射路径
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 加载spring配置类
* @return
*/
@Override
protected WebApplicationContext createRootApplicationContext() {
//初始化Spring容器对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(Spring_config.class);
return ctx;
}
}
四.对静态资源映射类
SpringMVC不配置映射路径是无法找到静态资源的。两种方式配置。
(1).通过继承WebMvcConfigurationSupport 实现。不推荐,因为springboot默认会找resources下的static的静态资源,是可以直接访问到的。
springboot 中,SpringMVCConfig通过继承WebMvcConfigurationSupport 方式来进行一些配置的话,那么还要配置静态资源映射路径才可以访问到静态资源。
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
/**
* 设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**")
.addResourceLocations("/pages/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**")
.addResourceLocations("/plugins/");
}
}
(2).直接在SpringMVC配置类中实现了WebMvcConfigurer 接口,上面的静态资源映射类可以不用了
@Configuration
@ComponentScan({"com.dengzhihong.controller"})
@EnableWebMvc
/**
* 实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
*/
public class SpringMvc_Config implements WebMvcConfigurer {
@Autowired
private ProjectInterception projectInterception;
@Autowired
private ProjectInterception2 projectInterception2;
/**
* 设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**")
.addResourceLocations("/pages/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**")
.addResourceLocations("/plugins/");
}
/**
* 注册mvc请求拦截器,"/**"是对所有请求拦截,如
* registry.addInterceptor(new TokenInterceptor())
* .addPathPatterns("/**")
* //排除不需要处理的路径
* .excludePathPatterns(new String[]{"/user/login","/user/loginVerification"});
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterception).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterception2).addPathPatterns("/books","/books/*");
}
}
三.SpringMVC拦截器
注意:这个SpringMVC配置类下面addInterceptors()方法中注册了两个个拦截器,springmvc对访问路径的拦截,相较于Servlet的过滤器Filter,通用性比较差。
过滤器和拦截器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
拦截器具体代码
/**
* SpringMVC拦截器:
* - 作用:
* 1. 在指定的方法调用前后执行预先设定的代码
* 2. 阻止原始方法的执行
* 3. 总结:增强
* -核心原理:AOP思想
*/
//受SpringMVC容器管理
@Component
public class ProjectInterception implements HandlerInterceptor {
/**
*原始方法调用前执行的内容
*返回值类型可以拦截控制的执行,true放行,false终止
* handler:被调用的处理器对象,本质上是一个方法对象,对反射技术中的Method对象进行了再包装
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("----------preHandle1");
return true;
}
/**
* 原始方法调用后执行的内容:
* 注意:如果处理器方法出现异常了,该方法不会执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("----------postHandle1");
}
/**
*原始方法调用完成后执行的内容:
* 注意:无论处理器方法内部是否出现异常,该方法都会执行。
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("----------afterCompletion1");
}
}
三.请求响应(重点)
1.controller层方式一
@Controller
//设置请求映射前缀
@RequestMapping("user")
public class RequestMapping_ {
//设置映射路径url,RequestParam接收表单或路径数据
@RequestMapping("/hello")
//设置响应体
@ResponseBody
public String hello(@RequestParam("name")String name, int age){
System.out.println(name+":"+age);
return "hello";
}
/**
* 传递实体参数user
*/
@RequestMapping("/user")
@ResponseBody
public String user(User user){
System.out.println(user);
return "user";
}
/**
* 嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
*/
@RequestMapping("/pojoContain")
@ResponseBody
public String classs(Classs classs){
System.out.println(classs);
return "classs";
}
/**
* 数组参数
*/
@RequestMapping("/array")
@ResponseBody
public String array(String[] likes){
System.out.println(Arrays.toString(likes));
return "array";
}
/**
* 集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
*/
@RequestMapping("/list")
@ResponseBody
public String list(@RequestParam List<String> likes){
System.out.println(likes);
return "list";
}
/**
* 集合参数json格式:
* 使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据。
* 作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
*/
@RequestMapping("/listJson")
@ResponseBody
public String listJson(@RequestBody List<String> likes){
System.out.println(likes);
return "listJson";
}
/**
* json传递实体参数user:json数据与形参对象属性名相同,定义POJO类型形参即可接收参数
*/
@RequestMapping("/userJson")
@ResponseBody
public String userJson(@RequestBody User user){
System.out.println(user);
return "userJson";
}
/**
* json实体集合参数:json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数
*/
@RequestMapping("/listUserJson")
@ResponseBody
public String listUserJson(@RequestBody List<User> users){
System.out.println(users);
return "usersJson";
}
/**
* 时间类型参数:使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd。
* 内部依赖Converter接口
*/
@RequestMapping("/date")
@ResponseBody
public String date(Date date,
@DateTimeFormat(pattern = "yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date2
){
System.out.println(date);
System.out.println(date1);
System.out.println(date2);
return "date";
}
}
2.响应
@Controller
public class Response_ {
/**
* 页面跳转
*/
@RequestMapping("/page")
public String index() throws IOException {
return "page.jsp";
}
/**
* 响应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;
}
/**
* 响应POJO集合对象:
* //返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据。
*/
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
3.最重要的Restful风格
通过对不同请求方式对映射路径进行方法区分,
如相同请求路径localhost:8080/users,不同请求方式,如post,get,put等。
/*@Controller
//代表所有方法都有@ResponseBody
@ResponseBody*/
//代表上面两个
@RestController
@RequestMapping("/users")
public class REST {
// @RequestMapping(method = RequestMethod.GET)
@GetMapping
public String get(){
System.out.println("get");
return "get";
}
// @RequestMapping(method = RequestMethod.POST)
@PostMapping
public String post(@RequestBody User user){
System.out.println(user);
return "post";
}
/**
* 路径参数
*/
// @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id){
System.out.println("delete:"+id);
return "delete";
}
// @RequestMapping(method = RequestMethod.PUT)
@PutMapping("/{id}")
public String put(@RequestBody User user,@PathVariable int id){
System.out.println(id);
System.out.println("put:"+user);
return "put";
}
}
四.全局异常处理器
在这里可以设置异常处理的方式
/**
* @RestControllerAdvice用于标识当前类为REST风格对应的异常处理器。
* 说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能
*/
@RestControllerAdvice
public class ProjectExceptionAdvice {
/**
* 系统异常
* 作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行。
* 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常。
*/
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
/**
* 业务异常
*/
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),null,ex.getMessage());
}
/**
*除了自定义的其他异常处理器
*/
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
}
}
五.项目完整代码演示
因为上面是对SpringMVC的介绍,所以下面代码不会全部用到,项目结构上图。
一.pom依赖
<?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>spring6_SSM</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--切面-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--spring整合mybatis-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</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>
二.resources下jdbc.properties准备
三.domain实体类,setter和Getter省略
public class Book {
private Integer id ;
private String type ;
private String name ;
private String description ;
}
四.dao层
public interface BookDao {
@Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
public int save(Book book); //返回值表示影响的行数
@Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
public int update(Book book);
@Delete("delete from tbl_book where id = #{id}")
public int 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();
}
五.config配置层
(1)Jdbc_Config配置类
public class Jdbc_Config {
@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;
}
@Bean
public PlatformTransactionManager platformTransactionManager(DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
六.Mybatis_Config
public class Mybatis_Config {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setTypeAliasesPackage("com.dengzhihong.domain");
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.dengzhihong.dao");
return mapperScannerConfigurer;
}
}
七.SpringMVC容器配置类ServletContainnerInit
public class ServletContainnerInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{Spring_Config.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvc_Config.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("utf-8");
return new Filter[]{characterEncodingFilter};
}
}
八.spring容器配置类Spring_Config
@Configuration
@ComponentScan({"com.dengzhihong.service"})
@PropertySource("classpath:jdbc.properties")
@Import({Jdbc_Config.class,Mybatis_Config.class})
@EnableTransactionManagement
public class Spring_Config {
}
九.springMVC配置类SpringMvc_Config
@Configuration
@ComponentScan({"com.dengzhihong.controller"})
@EnableWebMvc
/**
* 实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
*/
public class SpringMvc_Config implements WebMvcConfigurer {
@Autowired
private ProjectInterception projectInterception;
@Autowired
private ProjectInterception2 projectInterception2;
/**
* 设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**")
.addResourceLocations("/pages/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**")
.addResourceLocations("/plugins/");
}
/**
* 注册mvc请求拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterception).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterception2).addPathPatterns("/books","/books/*");
}
}
十.controller层下Code类
用于设置对不同响应状态码的设置
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
public static final Integer SYSTEM_ERR = 50001;
public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
public static final Integer SYSTEM_UNKNOW_ERR = 59999;
public static final Integer BUSINESS_ERR = 60002;
}
十一.controller层下Result类
用于封装响应码和响应数据,setter和Getter省略
public class Result {
private Object data;
private Integer code;
private String msg;
public Result() {
}
public Result(Integer code,Object data) {
this.data = data;
this.code = code;
}
public Result(Integer code, Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
}
十二.controller层下ProjectExceptionAdvice类
全局异常处理器,对于不同异常进行处理
/**
* @RestControllerAdvice用于标识当前类为REST风格对应的异常处理器。
* 说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能
*/
@RestControllerAdvice
public class ProjectExceptionAdvice {
/**
* 系统异常
* 作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行。
* 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常。
*/
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
/**
* 业务异常
*/
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),null,ex.getMessage());
}
/**
*除了自定义的其他异常处理器
*/
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
}
}
十三.controller层
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
@Qualifier("bookService")
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
if (flag){
return new Result(Code.SAVE_OK,null);
}else {
return new Result(Code.SAVE_ERR,null);
}
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
if (flag){
return new Result(Code.UPDATE_OK,null);
}else {
return new Result(Code.UPDATE_ERR,null);
}
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean falg = bookService.delete(id);
if (falg){
return new Result(Code.DELETE_OK,null);
}else {
return new Result(Code.DELETE_ERR,null);
}
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
Book book = bookService.getById(id);
if (book!=null){
return new Result(Code.GET_OK,book);
}else {
return new Result(Code.GET_ERR,book);
}
}
@GetMapping
public Result getAll() {
List<Book> bookList = bookService.getAll();
if (bookList.size()>0){
return new Result(Code.GET_OK,bookList);
}else {
return new Result(Code.GET_ERR,null);
}
}
}
最后看个图