2.4.9 SpringMVC avanzado, interacción asincrónica ajax (RequestBody, ResponseBody), estilo de programación RESTful, método de carga de archivos, mecanismo de manejo de excepciones, uso de interceptor

Tabla de contenido

springmvc avanzado

Una interacción asincrónica ajax

1.1 @RequestBody

1.2 @ResponseBody

Dos DESCANSADOS

2.1 Qué es RESTful

Carga de tres archivos

3.1 Tres elementos de la carga de archivos

3.2 Principio de carga de archivos

3.3 Carga de un solo archivo

3.4 Carga de varios archivos

Manejo de cuatro excepciones

4.1 La idea del manejo de excepciones

4.2 manejador de excepciones personalizado

4.3 Mecanismo de manejo de excepciones de la web

Cinco interceptores

5.1 El papel del interceptor (interceptor)

5.2 La diferencia entre interceptor y filtro

5.3 Inicio rápido

5.4 Cadena interceptora

5.5 Resumen de conocimientos


 

 

springmvc avanzado

contenido principal:


Una interacción asincrónica ajax

De forma predeterminada, Springmvc usa MappingJackson2HttpMessageConverter para convertir datos json, que deben agregarse al paquete Jackson; al mismo tiempo, use <mvc: annotation-drive />

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>


1.1 @RequestBody

Esta anotación se usa para la declaración formal de parámetros del método Controller. Cuando se envía usando ajax y especificando contentType como json, se convierte al objeto POJO correspondiente a través de la interfaz HttpMessageConverter.


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--引入js资源, 注意下面的script标签不要自闭合, 否则后面的显示不出来--%>
<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
    <%--ajax异步交互--%>
    <button id="btn1">ajax异步提交</button>

    <script>
        $("#btn1").click(function () {

            let url = '${pageContext.request.contextPath}/user/ajaxRequest';
            let data = '[{"id":1,"username":"张三"},{"id":2,"username":"李四"}]';

            $.ajax({
                type: 'POST',
                url: url,
                data : data,
                contentType : 'application/json;charset=utf-8',
                success: function (resp) {
                    alert(JSON.stringify(resp));
                }
            })
        })
    </script>
</body>
</html>
    /*
        ajax异步交互  [{"id":1,"username":"张三"},{"id":2,"username":"李四"}]
     */
        @RequestMapping("/ajaxRequest")
        public void ajaxRequest(@RequestBody List<User> list){
            System.out.println(list);
        }

 

1.2 @ResponseBody

Esta anotación se utiliza para convertir el objeto devuelto por el método Controller en datos en un formato específico a través de la interfaz HttpMessageConverter, como json, xml, etc., y responder al cliente a través de Response.

    /*
        ajax异步交互  [{"id":1,"username":"张三"},{"id":2,"username":"李四"}]
     */
        @RequestMapping("/ajaxRequest")
        @ResponseBody
        public List<User> ajaxRequest(@RequestBody List<User> list){
            System.out.println(list);
            return list;
        }

 


Dos DESCANSADOS

2.1 Qué es RESTful

Restful es un estilo de arquitectura de software y un estilo de diseño, no un estándar. Solo proporciona un conjunto de principios y restricciones de diseño. Utilizado principalmente para el software de interacción cliente-servidor, el software diseñado en base a este estilo puede ser más conciso, más estratificado y más fácil de implementar mecanismos de almacenamiento en caché.
Las solicitudes de estilo relajante usan "url + modo de solicitud" para indicar el propósito de una solicitud. Los cuatro verbos en el protocolo HTTP que indican el modo de operación son los siguientes:

  • OBTENER: Leer
  • POST: Crear
  • PUT : 更新 (Actualizar)
  • BORRAR: Eliminar

2.2 Implementación de código
@PathVariable

Se usa para recibir el valor del marcador de posición en la dirección de solicitud RESTful

package com.lagou.controller;

@Controller
@RequestMapping("/restful")
public class RestfulController {

    /*
        根据id进行查询
        localhost:8080/项目名/restful/user/2 + get请求方式  404  findById:2
     */
    // 下面的method表示只能用get方式请求,  {...}是个占位符, 里面写参数名称
    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    public String findById(@PathVariable Integer id){
        // 调用service方法完成对id为2的这条记录的查询
        // 问题:findById方法中怎么才能获取restful编程风格中url里面占位符的值
        // 使用 PathVariable注解 获取占位符的值, 如上 ↑
        return "findById: "+ id ;
    }
}

 

@RestController

El estilo RESTful se usa principalmente para el desarrollo de proyectos de separación de front-end y back-end. El front-end interactúa con el servidor de forma asíncrona a través de ajax. Nuestro procesador generalmente devuelve datos json, por lo que @RestController se usa para reemplazar las dos anotaciones @Controller y @ ResponseBody.

package com.lagou.controller;

@RestController //这是个组合主键:组合@Controller + @ResponseBody
@RequestMapping("/restful")
public class RestfulController {

    /*
        根据id进行查询
        localhost:8080/项目名/restful/user/2 + get请求方式  404  findById:2
     */
    // 下面的GetMapping表示只能用get方式请求,  {...}是个占位符, 里面写参数名称
    @GetMapping("/user/{id}") // @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    //@ResponseBody // 该注解会把return后面的直接以字符串形式返回给浏览器, 而不走视图解析器
    public String findById(@PathVariable Integer id){
        // 调用service方法完成对id为2的这条记录的查询
        // 问题:findById方法中怎么才能获取restful编程风格中url里面占位符的值
        // 使用 PathVariable注解 获取占位符的值, 如上 ↑
        return "findById: "+ id ;
    }

    /*
        新增方法
     */
    // 下面的PostMapping就表示后面的一长串
    @PostMapping("/user") // @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String post(){
        // 新增
        return "post";
    }

    /*
        更新方法
     */
    @PutMapping("/user")
    public String put(){
        // 更新操作
        return "put";
    }

    /*
        删除方法
     */
    @DeleteMapping("/user/{id}")
    public String delete(@PathVariable Integer id){

        return "delete" + id;
    }
}
}

 

Carga de tres archivos

3.1 Tres elementos de la carga de archivos

  • Tipo de elemento de formulario = "archivo"
  • El método del método de envío del formulario = "POST", ¿puede haber un cuerpo de solicitud
  • El atributo enctype del formulario es multipart form enctype = "multipart / form-data"

 

3.2 Principio de carga de archivos

Cuando el formulario se modifica a un formulario de varias partes, request.getParameter () dejará de ser válido.

Cuando el enctype del formulario es application / x-www-form-urlencoded , el
      formato del contenido del cuerpo del formulario es: nombre = valor y nombre = valor

Cuando el valor enctype del formulario es mutilpart / form-data , el contenido del cuerpo de la solicitud se convierte en un formulario de varias partes:

3.3 Carga de un solo archivo

Análisis de pasos


1) carga de archivo de importación pom.xml y coordenadas io

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

2) Analizador de carga de archivos de configuración Spring-mvc

    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定文件上传的最大值为5MB,5*1024*1024 -->
        <property name="maxUploadSize"  value="5242880"></property>
        <!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
        <property name="maxInMemorySize" value="40960"></property>
    </bean>

3) Escriba el código de carga del archivo

<%--
  Created by IntelliJ IDEA.
  User: Szc.0713
  Date: 2020/6/24
  Time: 16:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <%--编写一个满足文件上传三要素的表单
        1.表单的提交方式必须是post
        2.表单的enctype属性必须要修改成multipart/form-data
        3.表单中必须要有文件上传项
    --%>
    <form action="${pageContext.request.contextPath}/fileupload" method="post" enctype="multipart/form-data">

        名称:<input type="text" name="username"> <br>
        文件:<input type="file" name="filePic"> <br>
            <input type="submit" value="单文件上传">
    </form>

</body>
</html>
package com.lagou.controller;

@Controller
public class FileUploadController {


    /*
        单文件上传
     */
    // 上传文件类型为下面的multipartfile
    @RequestMapping("/fileupload")
    public String fileUpload(String username, MultipartFile filePic) throws IOException {

        //获取表单的提交参数,完成文件上传
        System.out.println(username);

        // 获取原始的文件上传名 a.txt  abc
        String originalFilename = filePic.getOriginalFilename();
        filePic.transferTo(new File("D:/upload/"+originalFilename));

        return "success";
    }
}

 

3.4 Carga de varios archivos

<%--
  Created by IntelliJ IDEA.
  User: Szc.0713
  Date: 2020/6/24
  Time: 16:35
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>


    <%--编写一个满足文件上传三要素的表单
        1.表单的提交方式必须是post
        2.表单的enctype属性必须要修改成multipart/form-data
        3.表单中必须要有文件上传项
    --%>
  
    <%--实现多文件上传--%>
    <form action="${pageContext.request.contextPath}/filesupload" method="post" enctype="multipart/form-data">

        名称:<input type="text" name="username"> <br>
        文件1:<input type="file" name="filePic"> <br>
        文件2:<input type="file" name="filePic"> <br>
        <input type="submit" value="多文件上传">
    </form>
</body>
</html>
    /*
      多文件上传
   */
    @RequestMapping("/filesupload")
    public String filesUpload(String username, MultipartFile[] filePic) throws IOException {

        //获取表单的提交参数,完成文件上传
        System.out.println(username);

        // 获取原始的文件上传名 a.txt  abc
        for (MultipartFile multipartFile : filePic) {
            String originalFilename = multipartFile.getOriginalFilename();
            multipartFile.transferTo(new File("D:/upload/"+originalFilename));

        }
        return "success";
    }

 

Manejo de cuatro excepciones

4.1 La idea del manejo de excepciones

En Java, generalmente hay dos formas de manejar las excepciones:
una es el procesamiento de captura del método actual (try-catch), este método de procesamiento provocará el acoplamiento del código comercial y el código de manejo de excepciones.
La otra no es procesarlo por sí mismo, sino arrojarlo a la persona que llama para que lo procese (arroja), y la persona que llama lo arroja a su persona que llama, es decir, vomitar.

Sobre la base de este método, se deriva el mecanismo de manejo de excepciones de SpringMVC.

El dao, el servicio y el controlador del sistema se lanzan hacia arriba a través de throws Exception, y finalmente el controlador front-end springmvc se entrega al controlador de excepciones para el manejo de excepciones, como se muestra a continuación:

 

4.2 manejador de excepciones personalizado

Análisis de pasos


1) Cree una clase de controlador de excepciones para implementar HandlerExceptionResolver

package com.lagou.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 全局异常处理类, 实现异常处理器接口
public class GlobalExceptionResolver implements HandlerExceptionResolver {

    /*
        Exception e:实际抛出的异常对象
     */

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
        // 进行具体的异常处理 产生异常后,跳转到一个最终的异常页面
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("error",e.getMessage());
        modelAndView.setViewName("error");

        return modelAndView;
    }
}

2) Configurar el controlador de excepciones

    <!--配置自定义的异常处理器-->
    <bean id="globalExceptionResolver" class="com.lagou.exception.GlobalExceptionResolver"></bean>

3) Escribe una página de excepción

<%--
  Created by IntelliJ IDEA.
  User: Szc.0713
  Date: 2020/6/21
  Time: 12:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>success... </h3>

    <% System.out.println("视图执行了....");%>
</body>
</html>

4) Prueba de salto anormal

package com.lagou.controller;

@Controller
public class ExceptionController {
    
    @RequestMapping("/testException")
    public String testException(){

        int i = 1/0;

        return "success";

    }
}

 

4.3 Mecanismo de manejo de excepciones de la web

    <!--处理404异常
    产生异常, 跳转到location-->
    <error-page>
        <error-code>404</error-code>
        <location>/404.jsp</location>
    </error-page>

    <!--处理500异常-->
    <error-page>
        <error-code>500</error-code>
        <location>/500.jsp</location>
    </error-page>

 

Cinco interceptores

5.1 El papel del interceptor (interceptor)

El interceptor de Spring MVC es similar al filtro en el desarrollo de Servlet, que se utiliza para preprocesar y posprocesar el procesador.
Los interceptores están conectados en un cierto orden en una cadena, que se llama Cadena Interceptora (InterceptorChain). Al acceder al método o campo interceptado, los interceptores de la cadena de interceptores serán llamados en el orden definido anteriormente. El interceptor es también una realización concreta de la idea AOP.

 

5.2 La diferencia entre interceptor y filtro

La diferencia entre el interceptor y el filtro se muestra en la figura:

 

 

5.3 Inicio rápido

Análisis de pasos

1) Cree una clase de interceptor para implementar la interfaz HandlerInterceptor

package com.lagou.interceptor;

public class MyInterceptor1 implements HandlerInterceptor {


    /*
        preHandle: 在目标方法执行之前 进行拦截   return false:不放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle....");

        return true;
    }


    /*
        postHandle: 在目标方法执行之后,视图对象返回之前,执行的方法
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....");
    }

    /*
        afterCompletion:在流程都执行完成后,执行的方法
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("afterCompletion....");


    }
}

2) Configurar el interceptor

    <!--配置拦截器
        可以配置多个-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
            <bean class="com.lagou.interceptor.MyInterceptor1"></bean>  <!--采用这个拦截器-->
        </mvc:interceptor>

    </mvc:interceptors>

3) Prueba el efecto de interceptación del interceptor

Escribir controlador, enviar solicitud al controlador, saltar página

package com.lagou.controller;

@Controller
public class TargetController {

    @RequestMapping("/target")
    public String targetMethod(){
        System.out.println("目标方法执行了....");
        return "success";
    }
}

Escribir página jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>success... </h3>

    <% System.out.println("视图执行了....");%>
</body>
</html>

 

5.4 Cadena interceptora

Los interceptores se pueden usar solos en el desarrollo, o se pueden usar múltiples interceptores al mismo tiempo para formar una cadena de interceptores. Los pasos de desarrollo son los mismos que los de un solo interceptor, excepto que se registran varios registros al registrarse. Tenga en cuenta que el orden de registro aquí representa el orden de ejecución del interceptor.

Igual que el anterior, escriba una operación MyHandlerInterceptor2 para probar el orden de ejecución:

    <!--配置拦截器
        可以配置多个, 配置顺序代表执行顺序-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
            <bean class="com.lagou.interceptor.MyInterceptor1"></bean>  <!--采用这个拦截器-->
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/> <!--对所有controller类里面的所有方法都进行拦截-->
            <bean class="com.lagou.interceptor.MyInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
package com.lagou.interceptor;

public class MyInterceptor2 implements HandlerInterceptor {
    
    /*
        preHandle: 在目标方法执行之前 进行拦截   return false:不放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle2....");

        return true;
    }
    
    /*
        postHandle: 在目标方法执行之后,视图对象返回之前,执行的方法
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle2....");
    }

    /*
        afterCompletion:在流程都执行完成后,执行的方法
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("afterCompletion2....");
    }
}

 

 

5.5 Resumen de conocimientos

El método en el interceptor se describe a continuación:

 

Supongo que te gusta

Origin blog.csdn.net/chengh1993/article/details/110789139
Recomendado
Clasificación