SpringMVC入门详解超

一.什么是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);
        }
    }
}

最后看个图
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愛沢かりん

感谢您对我的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值