framework learning notes Day12 --- spring MVC

Restful Style Introduction

  • WebAPI

    • If a URL returns data instead of HTML, the URL is a web API (web interface)
  • Restful

    • A way to access the web API in the Rest style
  • Restful style

    • ① Different CRUD operations adopt different request modes
    • ② The background response data is in JSON format

HiddenHttpMethodFilter filter

  • summary

    • The form only supports get and post requests. If you want to support put and delete, you need to use the HiddenHttpMethodFilter filter
  • code implementation

    <!--post 2 put-->
    <form th:action="@{/rest/post2Put}" method="post">
        <input type="hidden" name="_method" value="put">
        news:<input type="text" name="msg"><br>
        <button type="submit">Submit</button>
    </form>
    
    <!--post 2 delete-->
    <form th:action="@{/rest/post2Delete}" method="post">
        <input type="hidden" name="_method" value="delete">
        news:<input type="text" name="msg"><br>
        <button type="submit">Submit</button>
    </form>
    
    //@RequestMapping(path = "/rest/post2Put",method = RequestMethod.PUT)
    @PutMapping("/rest/post2Put")
    public String post2Put(String msg){
        System.out.println("msg = " + msg);
        return "demo01";
    }
    
    @DeleteMapping("/rest/post2Delete")
    public String post2Delete(String msg){
        System.out.println("msg = " + msg);
        return "demo01";
    }
    
  • matters needing attention

    • You can only use post to simulate put and delete

Restful style query user

  • demand

    • Query user records by id
  • analysis

    http://localhost:8080/framework27/user/selectUserById?id=1: before
    http://localhost:8080/framework27/user/1: now, GET request
    
  • code implementation

    <a th:href="@{/user/1}">Restful Style query user</a>
    
    @GetMapping("/user/{userId}")
    public String selectUserById(@PathVariable Integer userId){
        System.out.println("userId = " + userId);
        return "demo02";
    }
    

Restful style delete user

  • demand

    • Delete user record according to id
  • analysis

    http://localhost:8080/framework27/user/deleteUserById?id=1: before
    http://localhost:8080/framework27/user/1: now, DELETE request
    
  • code implementation

    @DeleteMapping("/user/{userId}")
    public String deleteUserById(@PathVariable Integer userId){
        System.out.println("deleteUserById userId = " + userId);
        return "demo02";
    }
    
    <body>
    
    
    <div id="app">
    
        <!--post 2 delete-->
        <form method="post" id="deleteUserForm">
            <input type="hidden" name="_method" value="delete">
    
        </form>
    
        <a id="myA" th:href="@{/user/1}" @click.prevent="deleteUserById()">Restful Style delete user</a>
    </div>
    
    
    </body>
    <script th:src="@{/js/vue.js}"></script>
    <script>
    
    
        //3. The form initiates a request based on the href attribute value of the a tag
        var vue = new Vue({
            el: "#app",
            data: {},
            methods: {
                //1. Click the a tab
                deleteUserById() {
                    console.log("deleteUserById");
                    //2. Trigger form
                    var formEle = document.getElementById("deleteUserForm");
                    var aEle = document.getElementById("myA");
                    //3. The form initiates a request based on the href attribute value of the a tag
                    formEle.setAttribute("action", aEle.getAttribute("href"));
                    formEle.submit();
                }
            }
        })
    
    
    </script>
    

Restful style add user

  • demand

    • Add user record
  • analysis

    http://localhost:8080/framework27/user/addUser? Username = root & userpwd = root: before 
    http://localhost:8080/framework27/user? Username = root & userpwd = root: now, POST the request
    
  • code implementation

    @PostMapping("/user")
    public String addUser(User inputUser){
        System.out.println("addUser user = " + inputUser);
        return "demo04";
    }
    
    <form th:action="@{/user}" method="post" >
        <input type="text" name="userName" ><br>
        <input type="text" name="userPwd" ><br>
        <input type="submit" value="Submit">
    </form>
    

Restful style login function

  • demand

    • Login function
  • analysis

    http://localhost:8080/framework27/user/login? Username = root & userpwd = root: before, post
    http://localhost:8080/framework27/user? Username = root & userpwd = root: now, POST the request
    
  • code implementation

    @PostMapping("/user/login")
    public String login(User inputUser){
        System.out.println("login user = " + inputUser);
        return "demo05";
    }
    
    <form th:action="@{/user/login}" method="post" >
        <input type="text" name="userName" ><br>
        <input type="text" name="userPwd" ><br>
        <input type="submit" value="Submit">
    </form>
    

Restful style modification user function

  • demand

    • Modify user record according to id
  • analysis

    http://localhost:8080/framework27/user/updateUserById? Userid = 1 & username = root & userpwd = root: before, post
    http://localhost:8080/framework27/user? Userid = 1 & username = root & userpwd = root: now, PUT request
    
  • code implementation

    @PutMapping("/user")
    public String updateUserById(User inputUser){
        System.out.println("updateUserById user = " + inputUser);
        return "demo04";
    }
    
    <form th:action="@{/user}" method="post" >
        <input type="hidden" name="_method" value="put">
        <input type="hidden" name="userId" value="250">
        <input type="text" name="userName" ><br>
        <input type="text" name="userPwd" ><br>
        <input type="submit" value="Submit">
    </form>
    

Spring MVC gets the common parameters sent by AJAX

  • code implementation

    <body>
    <div id="app">
        <form th:action="@{/ajax/getParamter}" method="post" @submit.prevent="getParamter()">
    
            <input type="text" name="userName" v-model="user.userName"><br>
            <input type="text" name="userPwd" v-model="user.userPwd"><br>
            <input type="submit" value="Submit">
        </form>
    </div>
    
    </body>
    <script th:src="@{/js/axios.js}"></script>
    <script th:src="@{/js/vue.js}"></script>
    <script>
    
        var vue = new Vue({
            el: "#app",
            data: {
                user: {
                    userId: 500,
                    userName: "",
                    userPwd: ""
                }
            },
            methods: {
                getParamter() {
                    var _this = this;
                    //Initiate asynchronous request / Ajax / getparameter
                    axios({
                        method: "get",
                        url: "/framework27/ajax/getParamter",
                        params: {
                            userId: _this.user.userId,
                            userName: _this.user.userName,
                            userPwd: _this.user.userPwd
                        }
                    }).then(function (res) {
                        var data = res.data;
                        console.log(data);
    
                    })
                }
            }
        })
    
    </script>
    
    @RequestMapping("/ajax/getParamter")
    public void getParamter(User user, HttpServletResponse response) throws IOException {
        System.out.println("user = " + user);
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //resultVO 2 json string
        response.setContentType("application/json;charset=utf-8");
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        response.getWriter().write(jsonStr);
    }
    

Spring MVC gets the request body json sent by AJAX

  • Code implementation 1

    <body>
    <div id="app">
        <form th:action="@{/ajax/getParamter}" method="post" @submit.prevent="getParamter()">
            <!--<input type="hidden" name="userId" value="250" v-model="user.userId">-->
            <input type="text" name="userName" v-model="user.userName"><br>
            <input type="text" name="userPwd" v-model="user.userPwd"><br>
            <input type="submit" value="Submit">
        </form>
    </div>
    
    </body>
    <script th:src="@{/js/axios.js}"></script>
    <script th:src="@{/js/vue.js}"></script>
    <script>
    
        var vue = new Vue({
            el: "#app",
            data: {
                user: {
                    userId: 500,
                    userName: "",
                    userPwd: ""
                }
            },
            methods: {
                getParamter() {
                    var _this = this;
                    //Initiate asynchronous request / Ajax / getparameter
                    axios({
                        method: "post",
                        url: "/framework27/ajax/getParamter2",
                        data: {
                            userId: _this.user.userId,
                            userName: _this.user.userName,
                            userPwd: _this.user.userPwd
                        }
                    }).then(function (res) {
                        console.log(res);
                    })
                }
            }
        })
    
    </script>
    
    @RequestMapping("/ajax/getParamter2")
    public void getParamter2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //① Read request body json
        BufferedReader bufferedReader = request.getReader();
        String content = null;
        StringBuffer sb = new StringBuffer();
        while ((content = bufferedReader.readLine()) != null) {
            sb.append(content);
        }
        String inputJsonStr = sb.toString();
        //②jsonStr 2 javabean
        User user = new ObjectMapper().readValue(inputJsonStr, User.class);
        System.out.println("user = " + user);
    
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //resultVO 2 json string
        response.setContentType("application/json;charset=utf-8");
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        response.getWriter().write(jsonStr);
    }
    
  • Code implementation 2

    @RequestMapping("/ajax/getParamter3")
    public void getParamter3(@RequestBody String inputJsonStr, HttpServletResponse response) throws IOException {
        //① Read request body json
        System.out.println("inputJsonStr = " + inputJsonStr);
        //② jsonStr2 javabean
        User user = new ObjectMapper().readValue(inputJsonStr, User.class);
        System.out.println("user = " + user);
    
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //resultVO 2 json string
        response.setContentType("application/json;charset=utf-8");
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        response.getWriter().write(jsonStr);
    }
    
  • Code implementation 3 (recommended)

    @RequestMapping("/ajax/getParamter4")
    public void getParamter4(@RequestBody User user, HttpServletResponse response) throws IOException {
        //① Read request body json
        //②jsonStr 2 javabean
        System.out.println("user = " + user);
    
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //resultVO 2 json string
        response.setContentType("application/json;charset=utf-8");
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        response.getWriter().write(jsonStr);
    }
    

Spring MVC response json string

  • summary

    • @ResponseBody: return the return value of the Handler method to the browser as the response body; If the return value is a javabean object, it will be automatically converted into a json string; At the same time, it also solves the problem of Chinese garbled code in the response text.
  • Code implementation 1

    @RequestMapping("/ajax/testResponse1")
    public void testResponse1(@RequestBody User user, HttpServletResponse response) throws IOException {
        //① Read request body json
        //②jsonStr 2 javabean
        System.out.println("user = " + user);
    
        response.setContentType("application/json;charset=utf-8");
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //① resultVO 2 json string
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        //② The json string is returned to the client as the response body
        response.getWriter().write(jsonStr);
    }
    
  • Code implementation 2

    @ResponseBody
    @RequestMapping("/ajax/testResponse2")
    public String testResponse2(@RequestBody User user, HttpServletResponse response) throws IOException {
        //① Read request body json
        //②jsonStr 2 javabean
        System.out.println("user = " + user);
    
        ResultVO resultVO = new ResultVO(true, "Operation succeeded!", null);
        //① resultVO 2 json string
        String jsonStr = new ObjectMapper().writeValueAsString(resultVO);
        //② The json string is returned to the client as the response body
        return jsonStr;//Previously, the default should be the logical view name; The return is a json string and is the response body.
    }
    
  • Code implementation 3 (recommended)

    @ResponseBody
    @RequestMapping("/ajax/testResponse3")
    public ResultVO testResponse3(@RequestBody User user, HttpServletResponse response) throws IOException {
        //① Read request body json
        //②jsonStr 2 javabean
        System.out.println("user = " + user);
        return new ResultVO(true, "Operation succeeded!", null);//Previously, the default should be the logical view name; The return is a json string and is the response body.
    }
    

Overview of exception mapping

  • summary
    • A project will contain many modules, and each module needs to be completed by division of labor. If the module in charge of Zhang San handles exceptions according to scheme a and the module in charge of Li Si handles exceptions according to method B... The ideas, codes and naming details of exception handling of each module are different, the whole project will be very chaotic.
    • Associate the exception type with a specific view to establish a mapping relationship. The spring MVC framework can help us manage exceptions.
  • benefit
    • Decouple exception control and core business, maintain them separately, and have a better structure
    • The same set of rules is used to manage exceptions at the entire project level

Annotation development exception handler

  • before

    @RequestMapping("/exception/testException1")
    public String testException1(int num) {
        try {
            if (num == 1) {
                String str = null;
                System.out.println(str.length());
    
            } else if (num == 2) {
                System.out.println(1 / 0);
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
            return "error1";
        } catch (ArithmeticException e) {
            e.printStackTrace();
            return "error2";
        }
        return "index";
    }
    
  • Now?

    @RequestMapping("/exception/testException2")
    public String testException2(int num) {
        if (num == 1) {
            String str = null;
            System.out.println(str.length());
        } else if (num == 2) {
            System.out.println(1 / 0);
        }
        return "index";
    }
    
    @ControllerAdvice
    public class MyExceptionAdvice {
    
    
        @ExceptionHandler(NullPointerException.class)
        public String handleNullPointerException(){
            System.out.println("MyExceptionAdvice handleNullPointerException");
            return "error1";
        }
    
        @ExceptionHandler(ArithmeticException.class)
        public String handleArithmeticException(){
            System.out.println("MyExceptionAdvice handleArithmeticException");
            return "error2";
        }
    
    
    }
    

Exception handling solutions

  • code implementation

    @ResponseBody
    @RequestMapping("/exception/testException3")
    public ResultVO testException3(int num) {
        try {
            if (num == 1) {
                String str = null;
                System.out.println(str.length());
            } else if (num == 2) {
                System.out.println(1 / 0);
            } else if (num == 3) {
                //Business exception (there is a problem with user input), such as: the input is empty, the format is incorrect
                throw new MyBusinessException("Be honest~~~");
            }
        } catch (ArithmeticException e) {
            e.printStackTrace();
            throw new MySystemException("System exception!");
        } catch (NullPointerException e) {
            e.printStackTrace();
            throw new MySystemException("System exception!");
        }
        return new ResultVO(true, "Operation succeeded!", null);
    }
    
    @ControllerAdvice
    public class MyExceptionAdvice {
    
        @ResponseBody
        @ExceptionHandler(MyBusinessException.class)
        public ResultVO handleBusinessException(Exception e) {
            //Prompt user
            return new ResultVO(false, "operation failed!", e.getMessage());
        }
    
    
        @ResponseBody
        @ExceptionHandler(MySystemException.class)
        public ResultVO handleSystemException(Exception e) {
            //Appease users
    
            //Send messages to developers
    
            //Log
            return new ResultVO(false, "operation failed!", e);
        }
    
    }
    

Spring, MyBatis, spring MVC integration

  • Development steps

    • ① Introduce related dependencies

    • ② Spring+MyBatis (mapper interface proxy)

      • 1.1 define the service interface and its implementation subclasses
      • 1.2. Define mapper interface
      • 1.3, write spring core xml
        • Scan annotation
        • Scan all mapper interface proxy objects
        • Configure SqlSessionFactoryBean
        • Configure DruidDataSource
      • 1.4 test passed
    • ③ Integrate spring MVC

      • Method 1: write web xml
        • Configure DispatcherServlet
          • Load spring MVC xml
        • Configure ContextLoaderListener
          • Load spring core xml
      • Mode 2: write web xml
        • Configure DispatcherServlet
          • Load spring MVC xml
          • Load spring core xml
    • ③ Integrate spring MVC

      <!--Mode 1-->
      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring-core.xml</param-value>
      </context-param>
      
      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
      
      <servlet>
          <servlet-name>mvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring-mvc.xml</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>mvc</servlet-name>
          <url-pattern>/</url-pattern>
      </servlet-mapping>
      
      <!--Mode II-->
      <servlet>
          <servlet-name>mvc</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring-*.xml</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>mvc</servlet-name>
          <url-pattern>/</url-pattern>
      </servlet-mapping>
      

Keywords: Java Spring Back-end RESTful mvc

Added by fr0mat on Tue, 04 Jan 2022 15:55:19 +0200