• SpringMVC 进阶


    SpringMVC 进阶

    一、拦截器

    SpringMVC 中 Interceptor 拦截器的主要作⽤是拦截⽤⼾的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证,或者是来判断⽤⼾是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两种:

    实现接⼝:org.springframework.web.servlet.HandlerInterceptor

    继承适配器:org.springframework.web.servlet.handler.HandlerInterceptorAdapter

    1.拦截器实现

    实现 HandlerInterceptor 接⼝
    /**
     * 拦截器的实现
     *  实现 HandlerInterceptor 接口
     */
    public class MyInterceptor01 implements HandlerInterceptor {
    
        /**
         * 在目标Handler(方法)执行前执行
         *      返回true:执行Handler方法
         *      返回false:阻止目标Handler执行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("目标Handler执行前执行MyInterceptor01 --> preHandle方法...");
            /**
             * 返回true:执行Handler方法
             * 返回false:阻止目标Handler执行
             */
            return true;
        }
    
        /**
         * 在 目标Handler(方法)执行后,视图生成前 执行
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("目标Handler执行后,视图生成前执行MyInterceptor01 --> postHandle方法...");
        }
    
        /**
         * 在 目标Handler(方法)执行后,视图生成后 执行
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("目标Handler执行后,视图生成后执行MyInterceptor01 --> afterCompletion方法...");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    拦截器xml配置
    
        <mvc:interceptors>
           
            <bean class="com.xxxx.springmvc.interceptor.MyInterceptor01"/>
        mvc:interceptors>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    
        <mvc:interceptors>
            
            <mvc:interceptor>
                
                
                <mvc:mapping path="/**"/>
                
                
                <mvc:exclude-mapping path="/url/*"/>
                <bean class="com.xxxx.springmvc.interceptor.MyInterceptor01"/>
            mvc:interceptor>
        mvc:interceptors>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    继承 HandlerInterceptorAdapter

    实际上最终还是 HandlerInterceptor 接⼝实现。

    子类实现类
    /**
     * 拦截器实现
     *      继承 HandlerInterceptorAdapter 适配器
     */
    public class MyInterceptor02 extends HandlerInterceptorAdapter {
    
        /**
         * 在 目标Handler(方法)执行前 执行
         *      返回true:执行Handler方法
         *      返回false:阻止目标Handler执行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("目标Handler执行前执行MyInterceptor02 --> preHandle方法...");
            return true;
        }
    
        /**
         * 在 目标Handler(方法)执行后,视图生成前 执行
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("目标Handler执行后,视图生成前执行MyInterceptor02 --> postHandle方法...");
        }
    
        /**
         * 在 目标Handler(方法)执行后,视图生成后 执行
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("目标Handler执行后,视图生成后执行MyInterceptor02 --> afterCompletion方法...");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    拦截器xml配置
    <mvc:interceptors>
        <mvc:interceptor>
            
            <mvc:mapping path="/**"/>
            
            <mvc:exclude-mapping path="/url/test01"/>
            <mvc:exclude-mapping path="/url/test02"/>
            <bean class="com.xxxx.springmvc.interceptor.MyInterceptor02"/>
        mvc:interceptor>
    mvc:interceptors>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    多个拦截器实现

    SpringMVC 框架⽀持多个拦截器配置,从⽽构成拦截器链,对客⼾端请求进⾏多次拦截操作。

    拦截器代码实现

    这⾥参考MyInterceptor01、MyInterceptor02代码

    拦截器xml配置
    <mvc:interceptors>
            
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.xxxx.springmvc.interceptor.MyInterceptor02"/>
            mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
                <bean class="com.xxxx.springmvc.interceptor.MyInterceptor01"/>
            mvc:interceptor>
        mvc:interceptors>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.拦截器应用 - 非法请求拦截

    使⽤拦截器完成⽤⼾是否登录请求验证功能

    用户控制器

    UserInfoController 定义

    /**
     * 用户模块
     *      用户登录 (不需要拦截)
     *      用户添加 (需要拦截)
     *      用户更新 (需要拦截)
     *      用户删除 (需要拦截)
     */
    @Controller
    @RequestMapping("/userInfo")
    public class UserInfoController {
        
        /**
         * 用户登录
         * @return
         */
        @RequestMapping("/login")
        public ModelAndView userLogin(HttpSession session){
            System.out.println("用户登录...");
            ModelAndView modelAndView = new ModelAndView();
            // 设置视图
            modelAndView.setViewName("success");
    
            // 如果用户登录,则设置用户对象到session作用域中
            User user = new User();
            user.setId(1);
            user.setUserName("admin");
            user.setUserPwd("123456");
            session.setAttribute("user", user);
    
            return modelAndView;
        }
    
        /**
         * 用户添加
         * @return
         */
        @RequestMapping("/add")
        public ModelAndView userAdd(){
            System.out.println("用户添加...");
            ModelAndView modelAndView = new ModelAndView();
            // 设置视图
            modelAndView.setViewName("success");
    
            return modelAndView;
        }
    
    
        /**
         * 用户更新
         * @return
         */
        @RequestMapping("/update")
        public ModelAndView userupdate(){
            System.out.println("用户更新...");
            ModelAndView modelAndView = new ModelAndView();
            // 设置视图
            modelAndView.setViewName("success");
    
            return modelAndView;
        }
    
    
        /**
         * 用户删除
         * @return
         */
        @RequestMapping("/delete")
        public ModelAndView userDelete(){
            System.out.println("用户删除...");
            ModelAndView modelAndView = new ModelAndView();
            // 设置视图
            modelAndView.setViewName("success");
    
            return modelAndView;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    页面定义

    success.jsp 定义

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
        

    登录页面

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    非法请求拦截器定义

    LoginInterceptor 定义

    public class LoginInterceptor extends HandlerInterceptorAdapter {
    
        /**
         * 在 目标方法执行前 执行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            // 获取session作用域中的user对象
            User user = (User) request.getSession().getAttribute("user");
            // 判断session作用域的user对象是否为空
            if (user == null){ // 如果为空,表示用户未登录
                // 拦截请求并跳转到登录页面
                response.sendRedirect(request.getContextPath() + "/login.jsp");
                // 不执行目标方法
                return false;
            }
            // 执行目标方法
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    拦截器xml配置

    servlet-context.xml 配置

    
    <mvc:interceptors>
        <mvc:interceptor>
            
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/userInfo/login"/>
            <mvc:exclude-mapping path="/uploadFile"/>
            <mvc:exclude-mapping path="/uploadFiles"/>
            <bean class="com.xxxx.springmvc.interceptor.LoginInterceptor"/>
        mvc:interceptor>
    mvc:interceptors>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    二、文件上传

    1.环境配置

    pom.xml文件修改
        
        <dependency>
          <groupId>commons-fileuploadgroupId>
          <artifactId>commons-fileuploadartifactId>
          <version>1.3.2version>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    servlet-context.xml修改
    
        <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            
            <property name="maxUploadSize">
                <value>104857600value>
            property>
            
            <property name="maxInMemorySize">
                <value>4096value>
            property>
        bean>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.代码实现

    单文件上传
    页面表单

    input 的type设置为file

    form 表单的method设为post

    form 表单的enctype设置为multipart/form-data,以⼆进制的形式传输数据

    • 1
    • 2
    • 3
    • 4
    代码实现
    /**
     * 单文件上传
     *
     * @return
     */
    @Controller
    public class FileController {
        @RequestMapping("/uploadFile")
        public String uploadFile(HttpServletRequest request, @RequestParam("file") MultipartFile file) {
            // 判断文件是否为空,如果不为空则进行对应的文件上传操作
            if (!file.isEmpty()) {
                try {
                    // 获取项目所在的路径 (绝对路径)
                    String path = request.getServletContext().getRealPath("/");
                    // 设置上传文件存放的目录
                    File uploadFile = new File(path + "/upload");
                    // 判断文件目录是否存在,如果不存在则新建对应的目录
                    if (!uploadFile.exists()) {
                        // 新建目录
                        uploadFile.mkdir();
                    }
    
                    // 获取上传文件的文件名
                    String originalName = file.getOriginalFilename();
                    // 获取上传文件的后缀名
                    String suffix = originalName.substring(originalName.lastIndexOf("."));
                    // 通过系统当前时间的毫秒数,生成随机的文件名
                    String fileName = System.currentTimeMillis() + suffix;
                    // 上传文件 (转存文件到指定目录)
                    file.transferTo(new File(uploadFile, fileName));
    
                    // 如果上传成功,设置作用域
                    request.setAttribute("msg", "文件上传成功!");
    
                } catch (IOException e) {
                    e.printStackTrace();
                    // 如果上传失败,设置作用域
                    request.setAttribute("msg", "文件上传失败!");
                }
            } else {
                // 如果上传文件不存在,设置作用域
                request.setAttribute("msg", "文件不存在!");
            }
    
            return "result";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    多文件件上传
    页面表单
        <form method="post" action="uploadFiles" enctype="multipart/form-data">
            <input type="file" name="files"/>
            <input type="file" name="files"/>
            <button>上传button>
        form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    代码实现
     @RequestMapping("/uploadFiles")
        public String uploadFiles(HttpServletRequest request, @RequestParam("files") List<MultipartFile> files){
    
            // 判断文件集合是否为空
            if (files != null && files.size() > 0) {
                for (MultipartFile file : files ) {
                    // 上传文件
                    saveFile(file, request);
                }
            }
            return "result";
        }
    
    
    
        /**
         * 上传文件
         * @param file
         * @param request
         */
        public void saveFile(MultipartFile file, HttpServletRequest request) {
            // 判断文件是否为空,如果不为空则进行对应的文件上传操作
            if (!file.isEmpty()) {
                try {
                    // 获取项目所在的路径 (绝对路径)
                    String path = request.getServletContext().getRealPath("/");
                    // 设置上传文件存放的目录
                    File uploadFile = new File(path + "/upload");
                    // 判断文件目录是否存在,如果不存在则新建对应的目录
                    if (!uploadFile.exists()) {
                        // 新建目录
                        uploadFile.mkdir();
                    }
    
                    // 获取上传文件的文件名
                    String originalName = file.getOriginalFilename();
                    // 获取上传文件的后缀名
                    String suffix = originalName.substring(originalName.lastIndexOf("."));
                    // 通过系统当前时间的毫秒数,生成随机的文件名
                    String fileName = System.currentTimeMillis() + suffix;
                    // 上传文件 (转存文件到指定目录)
                    file.transferTo(new File(uploadFile, fileName));
    
                    // 如果上传成功,设置作用域
                    request.setAttribute("msg","文件上传成功!");
    
                } catch (IOException e) {
                    e.printStackTrace();
                    // 如果上传失败,设置作用域
                    request.setAttribute("msg","文件上传失败!");
                }
            } else {
                // 如果上传文件不存在,设置作用域
                request.setAttribute("msg","文件不存在!");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    三、SSM 框架集成与测试

    1.环境配置

    配置 pom.xml
    修改 JDK 版本
      <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
      properties>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    添加坐标依赖
    <dependencies>
        
        <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.12version>
          <scope>testscope>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-contextartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-testartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-jdbcartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-txartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>org.aspectjgroupId>
          <artifactId>aspectjweaverartifactId>
          <version>1.9.5version>
        dependency>
    
    
        
        <dependency>
          <groupId>com.mchangegroupId>
          <artifactId>c3p0artifactId>
          <version>0.9.5.2version>
        dependency>
    
        
        <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatisartifactId>
          <version>3.5.3version>
        dependency>
    
        
        <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatis-springartifactId>
          <version>2.0.3version>
        dependency>
    
        
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.19version>
        dependency>
    
        
        <dependency>
          <groupId>org.slf4jgroupId>
          <artifactId>slf4j-log4j12artifactId>
          <version>1.7.2version>
        dependency>
        <dependency>
          <groupId>org.slf4jgroupId>
          <artifactId>slf4j-apiartifactId>
          <version>1.7.2version>
        dependency>
    
        
        <dependency>
          <groupId>com.github.pagehelpergroupId>
          <artifactId>pagehelperartifactId>
          <version>5.1.10version>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-webartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-webmvcartifactId>
          <version>5.2.4.RELEASEversion>
        dependency>
    
        
        <dependency>
          <groupId>javax.servletgroupId>
          <artifactId>javax.servlet-apiartifactId>
          <version>3.0.1version>
        dependency>
    
        
        <dependency>
          <groupId>com.fasterxml.jackson.coregroupId>
          <artifactId>jackson-coreartifactId>
          <version>2.10.0version>
        dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.coregroupId>
          <artifactId>jackson-databindartifactId>
          <version>2.10.0version>
        dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.coregroupId>
          <artifactId>jackson-annotationsartifactId>
          <version>2.10.0version>
        dependency>
    
        
        <dependency>
          <groupId>commons-fileuploadgroupId>
          <artifactId>commons-fileuploadartifactId>
          <version>1.3.2version>
        dependency>
    
      dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    设置资源目录和插件
    <build>
        <finalName>ssmfinalName>
        
        <resources>
          <resource>
            <directory>src/main/resourcesdirectory>
          resource>
          <resource>
            <directory>src/main/javadirectory>
            <includes>
              <include>**/*.xmlinclude>
              <include>**/*.propertiesinclude>
              <include>**/*.tldinclude>
            includes>
            <filtering>falsefiltering>
          resource>
        resources>
    
        <plugins>
          
          <plugin>
            <groupId>org.apache.maven.pluginsgroupId>
            <artifactId>maven-compiler-pluginartifactId>
            <version>2.3.2version>
            <configuration>
              <source>1.8source>
              <target>1.8target>
              <encoding>UTF-8encoding>
            configuration>
          plugin>
          
          <plugin>
            <groupId>org.eclipse.jettygroupId>
            <artifactId>jetty-maven-pluginartifactId>
            <version>9.4.27.v20200227version>
            <configuration>
              <scanIntervalSeconds>10scanIntervalSeconds>
              
              <httpConnector>
                <port>8080port>
              httpConnector>
              
              <webAppConfig>
                <contextPath>/ssmcontextPath>
              webAppConfig>
            configuration>
          plugin>
        plugins>
      build>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    配置 web.xml
    
    <web-app id="WebApp_ID" version="3.0"
             xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    
      
      <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring.xmlparam-value>
      context-param>
      
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
      listener>
    
      
      <filter>
        <description>char encoding filterdescription>
        <filter-name>encodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
          <param-name>encodingparam-name>
          <param-value>UTF-8param-value>
        init-param>
      filter>
      <filter-mapping>
        <filter-name>encodingFilterfilter-name>
        <url-pattern>/*url-pattern>
      filter-mapping>
    
      
      <servlet>
        <servlet-name>springMvcservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
          <param-name>contextConfigLocationparam-name>
          <param-value>classpath:servlet-context.xmlparam-value>
        init-param>
        
        <load-on-startup>1load-on-startup>
      servlet>
      <servlet-mapping>
        <servlet-name>springMvcservlet-name>
        
        <url-pattern>/url-pattern>
        
      servlet-mapping>
    
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    配置 servlet-context.xml
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        
        <context:component-scan base-package="com.xxxx.ssm.controller" />
    
        
        <mvc:annotation-driven>
            <mvc:message-converters>
                
                <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
                
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
            mvc:message-converters>
        mvc:annotation-driven>
    
    
        
        <mvc:default-servlet-handler/>
    
    
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
              id="internalResourceViewResolver">
            
            <property name="prefix" value="/WEB-INF/jsp/"/>
            
            <property name="suffix" value=".jsp"/>
        bean>
    
    
        
        <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            
            <property name="maxUploadSize">
                <value>104857600value>
            property>
            
            <property name="maxInMemorySize">
                <value>4096value>
            property>
        bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    配置 spring.xml

    在项⽬的 src/main/resources 下创建 spring.xml ⽂件, 内容如下

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
    
        
        <context:component-scan base-package="com.xxxx.ssm" >
            
            <context:exclude-filter type="annotation"
                                    expression="org.springframework.stereotype.Controller" />
        context:component-scan>
    
        
        <context:property-placeholder location="classpath:db.properties" />
    
        
        <aop:aspectj-autoproxy />
    
        
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}">property>
            <property name="jdbcUrl" value="${jdbc.url}">property>
            <property name="user" value="${jdbc.username}">property>
            <property name="password" value="${jdbc.password}">property>
        bean>
    
        
        <bean id="txManager"
              class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource">property>
        bean>
    
        
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="delete*" propagation="REQUIRED" />
            tx:attributes>
        tx:advice>
    
        
        <aop:config>
            <aop:pointcut id="servicePointcut"
                          expression="execution(* com.xxxx.ssm.service..*.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
        aop:config>
    
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource">property>
            <property name="configLocation" value="classpath:mybatis.xml" />
            <property name="mapperLocations" value="classpath:com/xxxx/ssm/mapper/*.xml" />
        bean>
    
        
        <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            
            <property name="basePackage" value="com.xxxx.ssm.dao" />
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    配置 mybatis.xml
    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.xxxx.ssm.po"/>
        typeAliases>
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
        plugins>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    配置 db.properties

    在项⽬的 src/main/resources 下创建 db.properties ⽂件,内容如下(mysql 创建数据库ssm)

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    jdbc.username=root
    jdbc.password=root
    
    • 1
    • 2
    • 3
    • 4
    添加 log4j.properties

    在项⽬的 src/main/resources 下创建 log4j.properties ⽂件,内容如下

    log4j.rootLogger=DEBUG, Console
    # Console
    log4j.appender.Console=org.apache.log4j.ConsoleAppender
    log4j.appender.Console.layout=org.apache.log4j.PatternLayout
    log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
    log4j.logger.java.sql.ResultSet=INFO
    log4j.logger.org.apache=INFO
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.添加源代码

    添加包

    在项⽬的 src/main/java 下创建对应的包结构

    com.xxxx.ssm.controller

    com.xxxx.ssm.service

    com.xxxx.ssm.mapper

    com.xxxx.ssm.dao

    com.xxxx.ssm.po

    添加 User.java

    在 com.xxxx.ssm.po 包下创建 JavaBean ⽂件 User.java (数据库字段对应如下)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    public class User {
    
        private Integer userId;
        private String userName;
        private String userPwd;
        private String userEmail;
        private Date createDate;
        private Date updateDate;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    添加UserDao.java 接口

    com.xxxx.ssm.dao 包下创建 UserDao.java ⽂件,提供对应的⽤⼾详情查询功能

    public interface UserDao {
        User queryUserByUserId(Integer userId);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    添加UserMapper.xml 映射文件

    com.xxxx.ssm.mapper 包下创建 UserMapper.xml ⽂件,提供select 查询标签配置

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.xxxx.ssm.dao.UserDao">
        <select id="queryUserByUserId" parameterType="int" resultType="com.xxxx.ssm.po.User">
               select user_id as userId,user_name as userName,user_pwd as userPwd
               from tb_user
               where user_id = #{userId}
          select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    添加 UserService.java

    com.xxxx.ssm.service 包下创建UserService.java ⽂件,提供⽤⼾详情查询⽅法

    @Service
    public class UserService {
    
        // 注入userDao
        @Autowired
        private UserDao userDao;
    
        public User queryUserByUserId(Integer userId){
            User user = userDao.queryUserByUserId(userId);
            return user;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    添加 HelloController.java

    在 com.xxxx.ssm.controller 包下创建 HelloController.java ⽂件

    @Controller
    public class UserController extends BaseController {
    
        // 注入userService
        @Autowired
        private UserService userService;
    
        @RequestMapping("/hello")
        public String hello (Model model){
    
    
            // 调用UserService层的方法
            User user = userService.queryUserByUserId(1);
            // 将数据存到model对象中
            model.addAttribute("user",user);
    
            return "hello";
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    添加 hello.jsp 视图⽂件

    在src/main/webapp/WEB-INF 创建jsp ⽬录,并在该⽬下创建hello.jsp ,展⽰查询的⽤⼾信息

    <body>
    	欢迎你,${user.userName}
    body>
    
    • 1
    • 2
    • 3

    四、RestFul URL

    模型 - 视图 - 控制器(MVC)是⼀个以设计界⾯应⽤程序为基础的设计思想。

    Restful ⻛格的 API 是⼀种软件架构⻛格,设计⻛格⽽不是标准,只是提供了⼀组设计原则和约束条件。它主要⽤于客⼾端和服务器交互类的软件。基于这个⻛格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    在Restful ⻛格中,⽤⼾请求的 url 使⽤同⼀个 url,⽤请求⽅式:get,post,delete,put…等⽅式对请求的处理⽅法进⾏区分,这样可以在前后台分离式的开发中使得前端开发⼈员不会对请求的资源地址产⽣混淆和⼤量的检查⽅法名的⿇烦,形成⼀个统⼀的接⼝。

    GET(SELECT):从服务器查询,可以在服务器通过请求的参数区分查询的⽅式。

    POST(CREATE):在服务器端新建⼀个资源,调⽤ insert 操作。

    PUT(UPDATE):在服务器端更新资源,调⽤ update 操作。

    PATCH(UPDATE):在服务器端更新资源(客⼾端提供改变的属性)。(⽬前 jdk7 未实现,tomcat7 不⽀持)。

    DELETE(DELETE):从服务器端删除资源,调⽤ delete 语句。

    1.SpringMVC 支持 RestFul URL 风格设计

    如何使用 Java 构造没有扩展名的RestFul URL ,如 /forms/1?

    SpringMVC 是通过 @RequestMapping 及 @PathVariable 注解提供的。

    通过如@RequestMapping(value=“/blog /{id}”, method = RequestMethod.DELETE),即可处理 /blog/1 的 delete请求。

    2.RestFul URL 映射地址配置

    准备环境
    添加 Account

    在 src/resources/java 对应的 com.xxxx.ssm.po ⽬录下新建 Account.java 实体类

    public class Account {
    
        private Integer id;
        private String aname;
        private String type;
        private Double money;
        private Integer userId;
        private Date createTime;
        private Date updateTime;
        private String remark;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    添加 AccountDao

    在 src/resources/java 对应的 com.xxxx.ssm.dao ⽬录下新建 AccountDao.java 接⼝类

    public interface AccountDao {
    
        public Account selectById(Integer id);
    
        public int save(Account account);
    
        public int update(Account account);
    
        public int delete(Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    添加 AccountMapper

    在 src/resources/java 对应的 com.xxxx.ssm.mapper ⽬录下新建 AccountMapper.xml 映射⽂件

    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.xxxx.ssm.dao.AccountDao" >
        <resultMap id="BaseResultMap" type="com.xxxx.ssm.po.Account" >
            <id column="id" property="id" jdbcType="INTEGER" />
            <result column="aname" property="aname" jdbcType="VARCHAR" />
            <result column="type" property="type" jdbcType="VARCHAR" />
            <result column="money" property="money" jdbcType="DOUBLE" />
            <result column="user_id" property="userId" jdbcType="INTEGER" />
            <result column="create_time" property="createTime" jdbcType="DATE" />
            <result column="update_time" property="updateTime" jdbcType="DATE" />
            <result column="remark" property="remark" jdbcType="VARCHAR" />
        resultMap>
        <sql id="Base_Column_List" >
        id, aname, type, money, user_id, create_time, update_time, remark
      sql>
        
        <select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
            select
            <include refid="Base_Column_List" />
            from tb_account
            where id = #{id,jdbcType=INTEGER}
        select>
    
        
        <delete id="delete" parameterType="java.lang.Integer" >
        delete from tb_account
        where id = #{id,jdbcType=INTEGER}
      delete>
    
        
        <insert id="save" parameterType="com.xxxx.ssm.po.Account" >
            insert into tb_account
            <trim prefix="(" suffix=")" suffixOverrides="," >
                <if test="id != null" >
                    id,
                if>
                <if test="aname != null" >
                    aname,
                if>
                <if test="type != null" >
                    type,
                if>
                <if test="money != null" >
                    money,
                if>
                <if test="userId != null" >
                    user_id,
                if>
                <if test="createTime != null" >
                    create_time,
                if>
                <if test="updateTime != null" >
                    update_time,
                if>
                <if test="remark != null" >
                    remark,
                if>
            trim>
            <trim prefix="values (" suffix=")" suffixOverrides="," >
                <if test="id != null" >
                    #{id,jdbcType=INTEGER},
                if>
                <if test="aname != null" >
                    #{aname,jdbcType=VARCHAR},
                if>
                <if test="type != null" >
                    #{type,jdbcType=VARCHAR},
                if>
                <if test="money != null" >
                    #{money,jdbcType=DOUBLE},
                if>
                <if test="userId != null" >
                    #{userId,jdbcType=INTEGER},
                if>
                <if test="createTime != null" >
                    #{createTime,jdbcType=DATE},
                if>
                <if test="updateTime != null" >
                    #{updateTime,jdbcType=DATE},
                if>
                <if test="remark != null" >
                    #{remark,jdbcType=VARCHAR},
                if>
            trim>
        insert>
    
        
        <update id="update" parameterType="com.xxxx.ssm.po.Account" >
            update tb_account
            <set >
                <if test="aname != null" >
                    aname = #{aname,jdbcType=VARCHAR},
                if>
                <if test="type != null" >
                    type = #{type,jdbcType=VARCHAR},
                if>
                <if test="money != null" >
                    money = #{money,jdbcType=DOUBLE},
                if>
                <if test="userId != null" >
                    user_id = #{userId,jdbcType=INTEGER},
                if>
                <if test="createTime != null" >
                    create_time = #{createTime,jdbcType=DATE},
                if>
                <if test="updateTime != null" >
                    update_time = #{updateTime,jdbcType=DATE},
                if>
                <if test="remark != null" >
                    remark = #{remark,jdbcType=VARCHAR},
                if>
            set>
            where id = #{id,jdbcType=INTEGER}
        update>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    添加 AccountService
    @Service
    public class AccountService {
    
        @Autowired
        private AccountDao accountDao;
    
        public Account selectById(Integer id){
            return accountDao.selectById(id);
        }
    
        public int saveAccount(Account account){
            return accountDao.save(account);
        }
    
        public int updateAccount(Account account){
            return accountDao.update(account);
        }
    
        public int delAccount(Integer id){
            return accountDao.delete(id);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    URL 映射地址配置
    /**
     * RestFul URL 配置
     *      1. 设置请求类型
     *          GET(查询)     @GetMapping
     *          DELETE(删除)  @DeleteMapping
     *          POST(添加)    @PostMapping
     *          PUT(更新)     @PutMapping
     *      2. URL设置时,不体现动作行为 (没有动词)
     *          例如:/account/1、/account/2、/account
     *      3. 定义参数格式
     *          1. 路径参数 ( @PathVariable )
     *          2. json格式 ( @RequestBody )
     *          3. 普通表单参数
     *      4. 设置响应数据
     *          json格式 ( @ResponseBody )
     */
    @Controller
    public class AccountController extends BaseController {
    
        @Autowired
        private AccountService accountService;
    
    
        /**
         * 查询操作
         *      传统的 URL 访问:
         *          http://localhost:8080/ssm/account/queryAccountById?id=1
         *      RestFul URL 访问:
         *          @GetMapping("/account/{id}")
         *          http://localhost:8080/ssm/account/1
         *      @PathVariable 将形参设置为参数路径,声明在形参前面
         * @param id
         * @return
         */
        // @RequestMapping("/account/queryAccountById")
        @GetMapping("/account/{id}")
        @ResponseBody
        public Account queryAccountById(@PathVariable  Integer id) {
            // 设置异常
            return accountService.selectById(id);
        }
    
    
        /**
         * 删除操作
         * @param id
         * @return
         */
        @DeleteMapping("/account/{id}")
        @ResponseBody
        public Map<String,String> deleteAccountById(@PathVariable Integer id) {
    
            // 调用service层的删除方法,返回受影响的行数
            int row = accountService.delAccount(id);
            // 判断受影响的行数是否大于0
            Map<String ,String> map = new HashMap<>();
            if (row > 0) {
                // 删除成功
                map.put("code","200");
                map.put("msg","删除成功!");
            } else {
                // 删除失败
                map.put("code","500");
                map.put("msg","删除失败!");
            }
            return  map;
        }
    
        /**
         * 添加操作
         * @param account
         * @return
         */
        @PostMapping("/account")
        @ResponseBody
        public Map<String,String> addAccount(@RequestBody Account account) {
            Map<String ,String> map = new HashMap<>();
    
            // 调用service层的添加方法,返回受影响的行数
            int row = accountService.saveAccount(account);
    
            // 判断受影响的行数是否大于0
            if (row > 0) {
                // 删除成功
                map.put("code","200");
                map.put("msg","添加成功!");
            } else {
                // 删除失败
                map.put("code","500");
                map.put("msg","添加失败!");
            }
            return map;
        }
    
    
        /**
         * 更新操作
         * @param account
         * @return
         */
        @PutMapping("/account")
        @ResponseBody
        public Map<String,String> updateAccount(@RequestBody Account account) {
            Map<String ,String> map = new HashMap<>();
    
            // 调用service层的添加方法,返回受影响的行数
            int row = accountService.updateAccount(account);
    
            // 判断受影响的行数是否大于0
            if (row > 0) {
                // 删除成功
                map.put("code","200");
                map.put("msg","更新成功!");
            } else {
                // 删除失败
                map.put("code","500");
                map.put("msg","更新失败!");
            }
            return map;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    五、全局异常统⼀处理

    SpringMVC 对于异常处理这块提供了⽀持,通过 SpringMVC 提供的全局异常处理机制,能够将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单⼀,也实现了异常信息的统⼀处理和维护

    全局异常实现⽅式 Spring MVC 处理异常有 3 种⽅式:

    1. 使⽤ Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver

    2. 实现 Spring 的异常处理接⼝ HandlerExceptionResolver ⾃定义⾃⼰的异常处理器

    3. 使⽤ @ExceptionHandler 注解实现异常处理

    1.异常处理实现

    全局异常处理方式一
    配置简单异常处理器

    配置 SimpleMappingExceptionResolver 对象

    
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    
    <property name="defaultErrorView" value="error">property>
    
    <property name="exceptionAttribute" value="ex">property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以在处理异常的⻚⾯获取异常信息

    ${ex}
    
    • 1
    使自定定义异常

    参数异常

    package com.xxxx.ssm.exception;
    
    /**
     * 自定义异常:参数异常
     */
    public class ParamsException extends RuntimeException {
        private Integer code = 300;
        private String msg = "参数异常!";
    
    
        public ParamsException() {
            super("参数异常!");
        }
    
        public ParamsException(String msg) {
            super(msg);
            this.msg = msg;
        }
    
        public ParamsException(Integer code) {
            super("参数异常!");
            this.code = code;
        }
    
        public ParamsException(Integer code, String msg) {
            super(msg);
            this.code = code;
            this.msg = msg;
        }
    
        public Integer getCode() {
            return code;
        }
    
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    业务异常

    package com.xxxx.ssm.exception;
    
    /**
     * 自定义异常:业务异常
     */
    public class BusinessException extends RuntimeException {
        private Integer code=400;
        private String msg="业务异常!";
    
    
        public BusinessException() {
            super("业务异常!");
        }
    
        public BusinessException(String msg) {
            super(msg);
            this.msg = msg;
        }
    
        public BusinessException(Integer code) {
            super("业务异常!");
            this.code = code;
        }
    
        public BusinessException(Integer code, String msg) {
            super(msg);
            this.code = code;
            this.msg = msg;
        }
    
        public Integer getCode() {
            return code;
        }
    
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    设置⾃定义异常与⻚⾯的映射
    
    <property name="exceptionMappings">
    <props>
    
    <prop key="com.xxxx.ssm.exception.BusinessException">errorprop>
    <prop key="com.xxxx.ssm.exception.ParamsException">errorprop>
    props>
    property>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使⽤ SimpleMappingExceptionResolver 进⾏异常处理,具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点,但该⽅法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适⽤。

    全局异常处理方式二(推荐)
    实现 HandlerExceptionResolver 接⼝
    /**
    * 全局异常统⼀处理
    */
    @Component
    public class GlobalExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse, Object handler, Exception ex) {
    ModelAndView mv = new ModelAndView("error");
    mv.addObject("ex","默认错误信息");
    return mv;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    ⾃定义异常处理
    /**
    * 全局异常统⼀处理
    */
    @Component
    public class GlobalExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse, Object handler, Exception ex) {
    ModelAndView mv = new ModelAndView("error");
    mv.addObject("ex","默认错误信息");
    // 判断是否是⾃定义异常
    if (ex instanceof ParamsException) {
    mv.setViewName("params_error");
    ParamsException e = (ParamsException) ex;
    mv.addObject("ex", e.getMsg());
    }
    if (ex instanceof BusinessException) {
    mv.setViewName("business_error");
    BusinessException e = (BusinessException) ex;
    mv.addObject("ex", e.getMsg());
    }
    return mv;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    使⽤实现 HandlerExceptionResolver 接⼝的异常处理器进⾏异常处理,具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。

    全局异常处理方式三

    ⻚⾯处理器继承 BaseController

    public class BaseController {
    @ExceptionHandler
    public String exc(HttpServletRequest request,HttpServletResponse response,Exception ex){
    request.setAttribute("ex", ex);
    if(ex instanceof ParamsException){
    return "error_param";
    }
    if(ex instanceof BusinessException){
    return "error_business";
    }
    return "error";
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使⽤ @ExceptionHandler 注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的 Controller 类继承于 BaseController 即可)、不需要附加Spring 配置等优点,但该⽅法对已有代码存在⼊侵性(需要修改已有代码,使相关类继承于 BaseController),在异常处理时不能获取除异常以外的数据。

    2.未捕获异常的处理

    在 web.xml 中通过(Websphere/Weblogic)或者(Tomcat)节点配置特定异常情况的显⽰⻚⾯。

      
      <error-page>
        <exception-type>java.lang.Throwableexception-type>
        <location>/500.jsplocation>
      error-page>
      <error-page>
        <error-code>404error-code>
        <location>/404.jsplocation>
      error-page>
      <error-page>
        <error-code>500error-code>
        <location>/500.jsplocation>
      error-page>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    Spring
    乐观锁和悲观锁在kubernetes中的应用
    计算机毕业设计(附源码)python医院药品进销存系统
    MYSQL 存储java.sql.Timestamp类型的数据时,mysql存储时间和java获取到的时间相差8小时
    Python爬虫基础(一):urllib库的使用详解
    Nosql redis高可用和持久化
    662. 二叉树最大宽度(难度:中等)
    JAVA第二课堂选课系统计算机毕业设计Mybatis+系统+数据库+调试部署
    h3c 网络设备清理所有配置
    关于MySql中explain结果filtered的理解
  • 原文地址:https://blog.csdn.net/diskindom/article/details/134433693