Explicación detallada de SpringMVC (Super Comprehensive)

Tabla de contenido

1. Introducción a SpringMvc

1. Revisa el patrón MVC

1.1 Concepto

El patrón de diseño MVC generalmente se refiere al marco MVC, M (Modelo) se refiere a la capa del modelo de datos, V (Vista) se refiere a la capa de vista y C (Controlador) se refiere a la capa de control. El propósito de usar MVC es separar los códigos de implementación de M y V, para que el mismo programa pueda tener diferentes expresiones. Entre ellos, la definición de Vista es relativamente clara, que es la interfaz de usuario.

​ En el desarrollo de proyectos Web es muy importante poder responder a las solicitudes de los usuarios en tiempo y forma. El usuario hace clic en una ruta URL en la página web, lo que equivale a que el usuario envíe una solicitud al servidor web. Después de obtener la solicitud, cómo analizar la entrada del usuario, ejecutar la lógica de procesamiento relevante y finalmente saltar a la página correcta para mostrar el resultado de la retroalimentación, estas tareas a menudo las completa la capa de control (Controlador).

​ Durante el proceso de solicitud, la información del usuario se encapsula en la clase de entidad Usuario, que pertenece a la capa del modelo de datos (Modelo) en el proyecto Web.

​ En la etapa de visualización de solicitudes, la página web de resultados redirigidos pertenece a la capa de vista (Ver).

Así, la capa de control es responsable de la interacción entre el primer plano y el fondo, la capa del modelo de datos encapsula los datos de entrada/salida del usuario y la capa de visualización selecciona la vista adecuada para mostrar el resultado final de la ejecución. El flujo de desarrollo y procesamiento se denomina patrón MVC.

Al aprender el desarrollo de Servlet y JSP, JavaBean es equivalente a Model, Servlet es equivalente a Controller y JSP es equivalente a View.

Resumido de la siguiente manera:

  • Capa de visualización (View): responsable de formatear los datos y presentarlos a los usuarios, incluida la visualización de datos, la interacción del usuario, la validación de datos, el diseño de la interfaz y otras funciones.
  • Capa de control (Controller): responsable de recibir y reenviar la solicitud, luego de procesar la solicitud, especificar la vista y enviar el resultado de la respuesta al cliente.
  • Capa de modelo de datos (Modelo): El objeto modelo tiene la mayoría de las tareas de procesamiento y es la parte principal de la aplicación.Es responsable del procesamiento de la lógica de datos (reglas comerciales) y la realización de operaciones de datos (es decir, acceder a datos en el base de datos).

1.2 Ventajas y desventajas

Todo tiene ventajas y desventajas, echemos un vistazo a las ventajas y desventajas de MVC.

1.2.1 Ventajas

  • Múltiples vistas comparten un modelo, lo que mejora en gran medida la reutilización del código
  • Los tres módulos de MVC son independientes entre sí, arquitectura débilmente acoplada
  • Los controladores aumentan la flexibilidad y la capacidad de configuración de las aplicaciones
  • Propicio para la gestión de ingeniería de software.

En resumen, finalmente podemos crear una arquitectura perfecta de acoplamiento flexible + alta reutilización + alta aplicabilidad a través del patrón de diseño MVC.

1.2.2 Desventajas

  • El principio es complicado.
  • Mayor complejidad de la estructura e implementación del sistema.
  • Las vistas tienen acceso ineficiente a los datos del modelo

2. El concepto de Spring MVC

1. Concepto

  • Spring MVC es un marco de desarrollo web ligero basado en el patrón de diseño MVC proporcionado por Spring, que es esencialmente equivalente a Servlet.
  • Spring MVC es la implementación más claramente estructurada de Servlet+JSP+JavaBean.
  • Dado que Spring MVC en sí mismo es parte del marco Spring, se puede decir que está perfectamente integrado con el marco Spring. Tiene ventajas inherentes en términos de rendimiento y es el marco de desarrollo web más convencional y la habilidad de desarrollo más popular en la industria actual.
  • En el marco Spring MVC, el controlador reemplaza el servlet para asumir la responsabilidad del controlador, que se utiliza para recibir la solicitud, llamar al modelo correspondiente para su procesamiento y devolver el resultado del procesamiento después de que el procesador complete el procesamiento comercial. El Controlador llama a la Vista correspondiente y presenta el resultado del procesamiento, y finalmente el cliente obtiene la información de respuesta.
  • Soporte basado en anotaciones y RESTful para Spring MVC.

2. Ventajas

  • División clara de roles, Spring MVC proporciona una división de roles muy clara en términos de Modelo, Vista y Controlador. Estos tres aspectos realmente cumplen sus funciones y son responsables de cada uno.
  • Función de configuración flexible, puede configurar la clase como Bean a través de XML.
  • Se proporciona una gran cantidad de interfaces de controlador y clases de implementación.Los desarrolladores pueden usar las clases de implementación de controlador proporcionadas por Spring o implementar interfaces de controlador por sí mismos.
  • Realmente no tiene nada que ver con la implementación de la capa Vista. No obliga a los desarrolladores a usar JSP, pero puede usar tecnologías como Velocity y FreeMarker según los requisitos del proyecto.
  • Apoyo a la internacionalización
  • programación a interfaz
  • Perfecta integración con Spring Framework

3. El primer programa Spring MVC

3.1 Pasos para usar

3.1.1 Crear una aplicación web e importar dependencias

<properties>
    <!-- spring版本号 -->
    <spring.version>4.0.2.RELEASE</spring.version>
    <!-- log4j日志文件管理包版本 -->
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
  </properties>
  <!--依赖-->
  <dependencies>
    <!-- junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <!-- JSTL标签类 -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <!-- servlet依赖的jar包start -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
    </dependency>
    <!-- 映入JSON -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-core-asl</artifactId>
      <version>1.9.4</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.4</version>
    </dependency>
    <!-- spring核心包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- 日志 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <!-- 格式化对象,方便输出日志 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.1.41</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <!--lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.2</version>
    </dependency>
  </dependencies>
  <build>
    <!--resources配置解决mybatis的mapperXml配置在java路径不被扫描的问题 -->
    <resources>
      <resource>
        <directory>src/main/java</directory>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <!-- 跳过测试 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>
    </plugins>
  </build>

3.1.2 Configuración de Spring MVC

​ Spring MVC se basa en Servlet, y DispatcherServlet es el núcleo de todo el marco Spring MVC, principalmente responsable de interceptar solicitudes y enviarlas a los procesadores correspondientes para su procesamiento. Entonces, para configurar Spring MVC, primero debe definir DispatcherServlet. Como con todos los servlets, el usuario debe estar configurado en web.xml.

Cree directorios java y de recursos en el directorio principal.

3.1.2.1 Definir DispatcherServlet (web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <!-- 部署 DispatcherServlet -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:config/springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
    <!--支持异步处理-->
    <async-supported>true</async-supported>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

Precauciones:

  1. Cuando se inicializa Spring MVC, buscará los archivos de configuración en el directorio WEB-INF de la aplicación. La regla de nomenclatura de los archivos de configuración es "servletName-servlet.xml", como springmvc-servlet.xml.
  2. También puede almacenar el archivo de configuración de Spring MVC en cualquier lugar del directorio de la aplicación, pero necesita usar el elemento init-param del servlet para cargar el archivo de configuración y especificar la ubicación del archivo de configuración de Spring MVC a través del parámetro contextConfigLocation.
<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
3.1.2.2 Creación de controladores

Cree el paquete com.hqyj.cl.controller en el directorio src y cree dos clases de controlador de estilo tradicional (implementando la interfaz del controlador) en el paquete, RegisterController y LoginController, para manejar los hipervínculos de "registro" e "inicio de sesión" en el página de inicio respectivamente solicitud. El controlador es la interfaz del controlador y solo hay un método handleRequest en la interfaz, que se usa para procesar solicitudes y devolver ModelAndView.

  1. Controlador de inicio de sesión
public class LoginController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest arg0,
                                      HttpServletResponse arg1) throws Exception {
    
    
        return new ModelAndView("/WEB-INF/jsp/login.jsp");   //注意文件路径是否在WEB-INF文件夹中
    }
}
  1. RegistrarControlador
public class RegisterController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest arg0,
                                      HttpServletResponse arg1) throws Exception {
    
    
        return new ModelAndView("/WEB-INF/jsp/register.jsp");
    }
}
3.1.2.3 Crear archivo de configuración de Spring MVC

Cree el archivo springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- LoginController控制器类,映射到"/login" -->
    <bean name="/login"
          class="com.hqyj.cl.controller.LoginController"/>
    <!-- LoginController控制器类,映射到"/register" -->
    <bean name="/register"
          class="com.hqyj.cl.controller.RegisterController"/>
</beans>
3.1.2.4 Crear página
  1. índice.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>Hello World!</h2>
未注册的用户,请
<a href="${pageContext.request.contextPath}/register"> 注册</a>!
<br /> 已注册的用户,去
<a href="${pageContext.request.contextPath}/login"> 登录</a>!
</body>
</html>
  1. iniciar sesión.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
login
</body>
</html>
  1. registro.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>register</title>
</head>
<body>
register
</body>
</html>
3.1.2.5 Configuración del servidor Tomcat

levemente

3.1.2.6 Pruebas

levemente

2. Solucionador de vistas Spring MVC (ViewResolver)

View Resolver (ViewResolver) es una parte importante de Spring MVC, responsable de resolver los nombres de vistas lógicas en objetos de vista específicos.

1. Clases de análisis de vista de uso común

1.1 Resolución de vista basada en URL

1.1.1 Resumen

​ UrlBasedViewResolver es una implementación simple de ViewResolver, que proporciona principalmente una forma de empalmar URL para resolver vistas.

1.1.2 Principio

​ UrlBasedViewResolver especifica el prefijo a través del atributo de prefijo, y el atributo de sufijo especifica el sufijo. Cuando el objeto ModelAndView devuelve un nombre de vista específico, concatenará el prefijo prefijo y el sufijo sufijo con el nombre de vista específico para obtener una ruta de carga específica del archivo de recursos de vista, cargando así el archivo de vista real y devolviéndolo al usuario.

1.1.3 Configuración

Para usar UrlBasedViewResolver, además de configurar los atributos de prefijo y sufijo, también debe configurar "viewClass" para indicar qué vista resolver. El código de ejemplo es el siguiente

<!--配置视图解析器之URLBasedViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <!--不能省略-->
    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
1.1.3.1 Descripción
  • El solucionador de vista anterior está configurado con dos atributos, prefijo y sufijo, lo que acorta la ruta de vista. Las rutas de vista de las clases de controlador RegisterController y LoginController en el primer programa Spring MVC solo necesitan proporcionar registro e inicio de sesión, y la resolución de vista agregará automáticamente el prefijo y el sufijo, que se resuelve aquí como /WEB-INF/jsp/register. jsp y /WEB-INF/jsp/login.jsp.
  • Al usar UrlBasedViewResolver, debe especificar el atributo viewClass para indicar qué vista resolver. Generalmente, InternalResourceView se usa con más frecuencia para mostrar jsp, pero cuando usamos JSTL, debemos usar JstlView.
  • El contenido almacenado en el directorio /WEB-INF/ no se puede obtener directamente a través de la solicitud de solicitud, por lo que, por razones de seguridad, el archivo jsp generalmente se coloca en el directorio WEB-INF.

1.2 InternalResourceViewResolver

1.2.1 Resumen

InternalResourceViewResolver es el "resolutor de vistas de recursos internos", que es el tipo de resolución de vistas más utilizado en el desarrollo diario. Es una subclase de URLBasedViewResolver y tiene todas las funciones de URLBasedViewResolver.

1.2.2 Principio

UrlBasedViewResolver especifica el prefijo a través del atributo de prefijo y el atributo de sufijo especifica el sufijo. Cuando el objeto ModelAndView devuelve un nombre de vista específico, concatenará el prefijo prefijo y el sufijo sufijo con el nombre de vista específico para obtener una ruta de carga específica del archivo de recursos de vista, cargando así el archivo de vista real y devolviéndolo al usuario.

1.2.3 Configuración

Use UrlBasedViewResolver Además de configurar los atributos de prefijo y sufijo, también debe configurar "viewClass" para indicar qué vista resolver. El código de ejemplo es el siguiente

<!--配置视图解析器之InternalResourceViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--可以省略-->
    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>    <!--注意路径-->
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
1.2.3.1 Descripción
  • InternalResourceViewResolver puede resolver automáticamente el nombre de vista devuelto en un objeto de tipo InternalResourceView.
  • InternalResourceView almacenará los atributos del modelo devueltos por el método del procesador del controlador en los atributos de solicitud correspondientes y luego redirigirá la solicitud a la URL de destino en el lado del servidor a través de RequestDispatcher. Es decir, cuando se usa InternalResourceViewResolver para resolver la vista, no es necesario especificar el atributo viewClass por separado.

3. Proceso de ejecución de Spring MVC

1. Diagrama de flujo de ejecución

[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace antirrobo, se recomienda guardar la imagen y cargarla directamente (img-UPAiYIZX-1682512822611) (G:\Desktop\Lesson Preparation\Class\ssm\ Courseware Map\Diagrama de flujo de ejecución de Spring MVC .png)]

2. Resumen del proceso de ejecución

El flujo de ejecución de SpringMVC es el siguiente

  1. El usuario hace clic en una ruta de solicitud para iniciar una solicitud de solicitud HTTP, que se enviará a DispatcherServlet (controlador frontal);
  2. DispatcherServlet solicita uno o más HandlerMapping (mapeador de procesador) y devuelve una cadena de ejecución (HandlerExecutionChain).
  3. DispatcherServlet envía la información del controlador devuelta por la cadena de ejecución a HandlerAdapter (adaptador del procesador);
  4. HandlerAdapter encuentra y ejecuta el controlador correspondiente (a menudo llamado controlador) de acuerdo con la información del controlador;
  5. Después de ejecutar el controlador, devolverá un objeto ModelAndView al HandlerAdapter (el objeto subyacente de Spring MVC, incluido el modelo de datos del modelo y la información de la vista de vista);
  6. Después de que HandlerAdapter recibe el objeto ModelAndView, lo devuelve a DispatcherServlet;
  7. Después de que DispatcherServlet reciba el objeto ModelAndView, solicitará ViewResolver (resolver de vista) para resolver la vista;
  8. ViewResolver coincide con el resultado de la vista correspondiente de acuerdo con la información de Vista y lo devuelve a DispatcherServlet;
  9. Después de recibir la vista de Vista específica, DispatcherServlet representa la vista, completa los datos del modelo en el campo de solicitud en la vista de Vista y genera la Vista final (vista);
  10. Las vistas son las encargadas de mostrar los resultados al navegador (cliente).

3. Interfaz Spring MVC

Los componentes involucrados en Spring MVC son DispatcherServlet (controlador frontal), HandlerMapping (mapeador de procesador), HandlerAdapter (adaptador de procesador), Handler (procesador), ViewResolver (resolver de vista) y View (vista). La descripción de la función de cada componente es la siguiente

3.1 DispatcherServlet

DispatcherServlet es el controlador frontal Como se puede ver en la Figura 1, todas las solicitudes de Spring MVC deben distribuirse uniformemente a través de DispatcherServlet.

DispatcherServlet es equivalente a un reenviador o unidad central de procesamiento, que controla la ejecución de todo el proceso y programa uniformemente cada componente para reducir el acoplamiento entre componentes y facilitar la expansión entre componentes.

3.2 Asignación de controladores

​ HandlerMapping es un mapeador de procesadores, su función es encontrar un controlador coincidente (Handler) mediante anotación o configuración XML según la ruta URL de la solicitud.

3.3 Adaptador del controlador

​ HandlerAdapter es un adaptador de procesador, cuya función es ejecutar el procesador relevante (Handler) de acuerdo con reglas específicas según el procesador (Handler) encontrado por el mapeador.

En la etapa de servlet, para resolver una solicitud correspondiente a un servlet, existen dos métodos

1. Cuando el método pase parámetros, pase uno más y busque el método de servlet correspondiente

2. Encapsule un baseServlet, que se utiliza para heredar el httpsservlet, e invóquelo durante la operación a través de la reflexión. Los servlets definidos más adelante heredarán el baseServlet

3.4 Manejador

El controlador es un procesador, a menudo llamado controlador, que es consistente con el papel que desempeña Java Servlet. Su función es ejecutar la lógica de procesamiento de solicitudes relacionadas, devolver los datos correspondientes y ver información, y encapsularlos en el objeto ModelAndView.

3.5 Ver resolución

View Resolver es un solucionador de vistas, su función es realizar operaciones de análisis y resolver el nombre de la vista lógica en una vista de vista real a través de la información de vista en el objeto ModelAndView (como devolver una página JSP real a través de una ruta JSP).

3.6 Ver

View es una vista, que en sí misma es una interfaz, y la clase de implementación admite diferentes tipos de vista (JSP, FreeMarker, Thymeleaf, etc.).

四、@Controller、@RequestMapping

La versión 2.5 de Spring agrega la función de anotación Spring MVC para reemplazar la configuración tradicional de Spring MVC basada en XML.

1. Ventajas de usar anotaciones

  • Se pueden escribir varios métodos de procesamiento en la clase de controlador basada en anotaciones y se pueden procesar varias solicitudes (acciones), lo que permite escribir operaciones relacionadas en la misma clase de controlador, lo que reduce el número de clases de controlador y facilita el mantenimiento posterior. .
  • Los controladores basados ​​en anotaciones no necesitan implementar asignaciones en archivos de configuración, solo necesitan usar @RequestMapping para anotar un método para el procesamiento de solicitudes.

2, @ controlador

La anotación @Controller se usa para declarar que una instancia de una clase es un controlador.

2.1 Pasos para usar

  1. Agregar anotaciones a la clase Controller
package com.hqyj.cl.controller;

import org.springframework.stereotype.Controller;

@Controller
public class AnnotationTest {
    
    
    // 方法代码
}
  1. análisis del paquete de configuración springmvc-servlet.xml

Spring MVC utiliza el mecanismo de escaneo para encontrar todas las clases de controlador basadas en anotaciones en la aplicación. Por lo tanto, para que el marco Spring MVC escanee la clase de controlador, debe declarar spring-context en el archivo de configuración y usar el elemento para especificar el paquete básico de la <context:component-scan/>clase de controlador (asegúrese de que todas las clases de controlador estén bajo el paquete base y sus subpaquetes).

<!-- 使用扫描机制扫描控制器类,控制器类都在com.hqyj.controller包及其子包下 -->
<context:component-scan base-package="com.hqyj.controller" />

3, @RequestMapping

  • Hay varios métodos para procesar solicitudes en un controlador, como agregar usuarios, modificar la información del usuario, eliminar usuarios específicos y obtener listas de usuarios según las condiciones, etc. en UserController. Cada método es responsable de diferentes operaciones de solicitud y @RequestMapping es responsable de asignar la solicitud al método de controlador correspondiente.
  • La anotación @RequestMapping se puede usar en clases o métodos. Usado en una clase, significa que todos los métodos en la clase que responden a las solicitudes usan esta dirección como la ruta principal.

3.1 Atributos comunes

3.1.1 atributo de valor

​ El atributo de valor es el atributo predeterminado de la anotación @RequestMapping, por lo que si solo existe el atributo de valor, se puede omitir el nombre del atributo y, si hay otros atributos, se debe escribir el nombre del atributo de valor.

3.1.1.1 Código de muestra
@RequestMapping(value="user")
@RequestMapping("user")

3.1.2 propiedad de ruta

Mismo uso que el atributo de valor

3.1.3 atributo de nombre

El atributo de nombre es equivalente al comentario del método, lo que facilita la comprensión del método.

3.1.3.1 Código de ejemplo
@RequestMapping(value = "user",name = "用户操作")

3.1.4 atributo de método

El atributo de método se utiliza para indicar qué solicitudes HTTP son compatibles con el método. Si se omite el atributo de método, el método admite todas las solicitudes HTTP.

3.1.4.1 Código de ejemplo
// 只支持 GET 请求
@RequestMapping(value = "selectAllUser",method = RequestMethod.GET)
// 指定支持多个 HTTP 请求,该方法同时支持 GET 和 POST 请求。
@RequestMapping(value = "checkUser",method = {
    
    RequestMethod.GET,RequestMethod.POST})

3.1.5 propiedad de parámetros

El atributo params se utiliza para especificar los parámetros especificados en la solicitud.

3.1.5.1 Código de ejemplo
// 请求中必须包含 type 参数时才能执行该请求
@RequestMapping(value = "selectAllUser",params = "type")
public String toUser() {
    
    
    return "userList";
}
// 请求中必须包含 type 参数,且 type 参数值为 1 时才能够执行该请求
@RequestMapping(value = "selectAllUser",params = "type=1")
public String toUser() {
    
    
    return "userList";
}

3.2 Asignación por URL de solicitud

3.2.1 Anotaciones a nivel de método

@Controller
public class UserController {
    
    
    @RequestMapping(value = "/user/login")
    public String login() {
    
    
        return "login";
    }
    @RequestMapping(value = "/user/register")
    public String register() {
    
    
        return "register";
    }
}

3.2.2 Anotaciones a nivel de clase

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @RequestMapping("/login")
    public String login() {
    
    
        return "login";
    }
    @RequestMapping("/register")
    public String register() {
    
    
        return "register";
    }
}

3.3 Mapeo por parámetros o métodos de solicitud

​ El valor de @RequestMapping indica la URL de la solicitud; el método indica el método de solicitud, que se establece aquí como una solicitud GET. Si es una solicitud POST, no puede ingresar al método de procesamiento de selectUserByUsername. params indica los parámetros de la solicitud, donde el nombre del parámetro es nombre de usuario.

@Controller
public class UserController {
    
    
    @RequestMapping(value = "/user/userList" method=RequestMethod.GET, params="username")
    public String selectUserByUsername(String username) {
    
    
        return "userList";
        
    @RequestMapping(value = "/user/userList2" method=RequestMethod.GET)
    public String selectUserByUsername2(@RequestParam("username") String username) {
    
    
        return "userList";
}

3.4 Tipos de parámetros

El tipo org.springframework.ui.Model, que es un tipo Spring MVC que contiene un mapa. Spring MVC creará objetos org.springframework.ui.Model cada vez que se llame a un método de manejo de solicitudes.

3.4.1 Tipo de modelo

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @RequestMapping("/register")
    public String register(Model model) {
    
    
        /*在视图中可以使用EL表达式${success}取出model中的值*/
        model.addAttribute("success", "注册成功");
        return "register";
    }
}

3.4.1 Caso

  1. controlador
@Controller
@RequestMapping(value = "user",name = "用户操作")
public class UserController {
    
    
    // 登录
    @RequestMapping("/login")
    public String login(Model model){
    
    
        /*在视图中可以使用EL表达式${info}取出model中的值*/
        model.addAttribute("info", "登录成功");
        return "index";
    }
}
  1. Página de inicio
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${info},系统首页!
</body>
</html>

Cinco, Spring MVC pasando parámetros

Hay muchas formas en que Spring MVC Controller puede recibir parámetros de solicitud, algunas son adecuadas para obtener métodos de solicitud, otras son adecuadas para métodos de solicitud posterior y otras son adecuadas para ambos. Existen principalmente las siguientes formas:

  • Recibir parámetros de solicitud a través del bean de entidad
  • Recibir los parámetros de la solicitud a través de los parámetros formales del método de procesamiento
  • Reciba los parámetros de la solicitud a través de HttpServletRequest
  • Reciba los parámetros de la solicitud en la URL a través de @PathVariable
  • Reciba los parámetros de la solicitud a través de @RequestParam

1. Recibir parámetros de solicitud a través del bean de entidad

Los parámetros de solicitud de recepción de Entity Bean se aplican a los métodos de solicitud de envío de obtención y publicación. Cabe señalar que el nombre de propiedad del Bean debe ser el mismo que el nombre del parámetro de solicitud. El código de ejemplo es el siguiente

@RequestMapping("/login")
public String login(User user, Model model) {
    
    
    if ("admin".equals(user.getUsername())
            && "112112".equals(user.getPassword())) {
    
    
        model.addAttribute("message", "登录成功");
        return "index"; // 登录成功,跳转到 index.jsp
    } else {
    
    
        model.addAttribute("message", "用户名或密码错误");
        return "login";
    }
}

url obtener solicitud método de fondo parámetros de empalme

2. Recibir los parámetros de la solicitud a través de los parámetros formales del método de procesamiento

Recibir parámetros de solicitud a través de los parámetros formales del método de procesamiento es escribir directamente los parámetros de formulario en los parámetros formales del método correspondiente de la clase del controlador, es decir, los nombres de los parámetros formales son exactamente los mismos que los nombres de los parámetros de solicitud. Este método de recibir parámetros es aplicable para obtener y publicar solicitudes de envío. El código de ejemplo es el siguiente

@RequestMapping("/login")
public String login(String username, String password, Model model) {
    
    
    if ("admin".equals(username)
            && "112112".equals(password)) {
    
    
        model.addAttribute("message", "登录成功");
        return "index"; // 登录成功,跳转到 index.jsp
    } else {
    
    
        model.addAttribute("message", "用户名或密码错误");
        return "login";
    }
}

3. Recibir parámetros de solicitud a través de HttpServletRequest

Al igual que el método de adquisición en la fase de servlet, los parámetros del método de la capa del controlador incluyen el parámetro HttpServletRequest y se pueden obtener los parámetros de la solicitud.

4. Recibe los parámetros de la solicitud en la URL a través de @PathVariable

@RequestMapping(value = "/login/{username}/{password}")
public String login(@PathVariable("username") String username, @PathVariable("password") String password) {
    
    
    System.out.println(username);
    System.out.println(password);
    return "index";
}

Al acceder http://localhost:8080/user/login/admin/123456a la ruta, el código anterior vinculará automáticamente las variables de plantilla {nombre de usuario} y {contraseña} en la URL a los parámetros del mismo nombre anotados por @PathVariable, a saber, nombre de usuario=admin, contraseña=123456.

5. Reciba los parámetros de la solicitud a través de @RequestParam

Utilice la anotación @RequestParam en el parámetro del método para especificar sus parámetros de solicitud correspondientes. @RequestParam tiene los siguientes tres parámetros:

  • valor: nombre del parámetro;
  • requerido: si se incluye este parámetro, el valor predeterminado es verdadero, lo que indica que la ruta de la solicitud debe incluir este parámetro, si no se incluye, se informará un error;
  • defaultValue: el valor del parámetro predeterminado, si se establece este valor, required=true no será válido y será falso automáticamente, si no se pasa este parámetro, se usará el valor predeterminado

La recepción de parámetros de solicitud a través de @RequestParam es aplicable a los métodos de solicitud de envío de obtención y publicación, el código de muestra es el siguiente

  1. Controlador de usuario
@RequestMapping("/goRequestParam")
private String goRequestParam(){
    
    
    return "requestParam";
}
@RequestMapping("/requestParam")
public String requestParam(
    @RequestParam(value = "username",required = true) String username, 
    @RequestParam(value = "password",required = false,defaultValue = "111") String password){
    
    
    System.out.println(username + " " + password);
    return "index";
}
  1. requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>RequestParam</title>
</head>
<body>
<form action="/user/requestParam" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="submit">
</form>
</body>
</html>
  1. índice.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
<a href="../user/login">登录</a><br>
<a href="../user/register">注册</a><br>
<a href="../user/goRequestParam">RequestParam</a><br>
</body>
</html>

​ La diferencia entre este método y "Recibir parámetros de solicitud a través de los parámetros formales del método de procesamiento" es la siguiente: cuando los parámetros de solicitud no son consistentes con los nombres de los parámetros recibidos, "Recibir parámetros de solicitud a través de los parámetros formales del método de procesamiento" no informará un error 400, mientras que "By @ RequestParam" recibe los parámetros de la solicitud" informará un error 400.

Seis, redirección y reenvío de Spring MVC

  • Los métodos de solicitud de Spring MVC se dividen en dos tipos: reenvío y redirección, que se procesan en la capa del controlador utilizando palabras clave de reenvío y redirección respectivamente.
  • En el marco Spring MVC, la declaración de devolución del método de procesamiento en la clase del controlador se reenvía de forma predeterminada , pero se reenvía a la vista.
  • La redirección consiste en dirigir al usuario desde la solicitud de procesamiento actual a otra vista (como JSP) o solicitud de procesamiento. Toda la información almacenada en la solicitud anterior (solicitud) se invalidará y entrará en un nuevo alcance de solicitud;
  • El reenvío consiste en reenviar la solicitud de procesamiento actual del usuario a otra vista o solicitud de procesamiento, y la información almacenada en la solicitud anterior no se invalidará.
  • El reenvío es un comportamiento del servidor, la redirección es un comportamiento del cliente.

1. Proceso de reenvío

  • El navegador del cliente envía una solicitud http y el servidor web acepta la solicitud, llama a un método interno para completar el procesamiento de la solicitud y las acciones de reenvío dentro del contenedor, y envía el recurso de destino al cliente; la ruta de reenvío aquí debe ser la URL bajo el mismo contenedor web, no se puede redirigir a otras rutas web y la solicitud en su propio contenedor se pasa en el medio.
  • Lo que se muestra en la barra de direcciones del navegador del cliente sigue siendo la ruta de su primera visita, es decir, el cliente no siente que el servidor haya hecho un reenvío. El comportamiento de reenvío es que el navegador solo realiza una solicitud de acceso.

2. Proceso de redirección

  • El navegador del cliente envía una solicitud http, y el servidor web envía una respuesta de código de estado 302 y la nueva ubicación correspondiente al navegador del cliente después de aceptarla. Cuando el navegador del cliente encuentra que es una respuesta 302, envía automáticamente una nueva solicitud http , y la URL de solicitud es la nueva dirección de ubicación, el servidor encuentra el recurso en función de esta solicitud y lo envía al cliente.
  • La ubicación aquí se puede redirigir a cualquier URL. Dado que el navegador vuelve a emitir la solicitud, no existe el concepto de entrega de la solicitud. La ruta de redirección se muestra en la barra de direcciones del navegador del cliente, y el cliente puede observar el cambio de dirección. El comportamiento de redirección es que el navegador realiza al menos dos solicitudes de acceso.

3. Caso

@RequestMapping("/login")
public String login() {
    
    
    //转发到一个请求方法(同一个控制器类可以省略/index/)
    return "forward:/user/isLogin";
}
@RequestMapping("/isLogin")
public String isLogin() {
    
    
    //重定向到一个请求方法
    return "redirect:/user/isRegister";
}
@RequestMapping("/isRegister")
public String isRegister() {
    
    
    //转发到一个视图
    return "register";
}

4. Asuntos que requieren atención

​ En el marco Spring MVC, ya sea redirección o reenvío, debe ajustarse a la configuración de la resolución de vista.Si se reenvía directamente a un recurso que no requiere DispatcherServlet, por ejemplo

return "forward:/html/my.html";

Debe configurar en springmvc-servlet.xml

<mvc:resources location="/html/" mapping="/html/**" />

7. @Autocableado y @Servicio

Las anotaciones @Autowired y @Service son necesarias para inyectar dependencias en los controladores Spring MVC.

1. Introducción

La anotación @Autowired pertenece al paquete org.springframework.beans.factory.annotation, que puede anotar variables, métodos y constructores de miembros de clase para completar el trabajo de ensamblaje automático;

La anotación @Service pertenece al paquete org.springframework.stereotype y registrará automáticamente la clase de anotación en el contenedor de Spring.

2. Caso

  1. springmvc-servlet.xml

Es necesario agregar elementos en el archivo de configuración springmvc-servlet.xml <component-scan/>para escanear paquetes básicos dependientes

<context:component-scan base-package="com.hqyj.cl.service"/>
  1. clase de entidad
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private String name;
    private String pwd;
}
  1. Crear la interfaz de UserService
public interface UserService {
    
    
    boolean login(User user);
    boolean register(User user);
}
  1. Cree una clase UserServiceImpl para implementar la interfaz UserService
@Service
public class UserServiceImpl implements UserService {
    
    
    @Override
    public boolean login(User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return true;
        }
        return false;
    }
    @Override
    public boolean register(User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return true;
        }
        return false;
    }
}

Nota: La función de agregar la anotación @Service es permitir que Spring escanee la clase

  1. Crear la clase UserController
@Controller
@RequestMapping("/user")
public class UserController {
    
    
    @Autowired
    private UserService userService;
    @RequestMapping("/login")
    public String getLogin(Model model) {
    
    
        User user = new User();
        user.setName("admin");
        user.setPwd("111");
        userService.login(user);
        model.addAttribute("user", user);
        return "login";
    }
    @RequestMapping("/register")
    public String getRegister(Model model) {
    
    
        User user = new User();
        user.setName("admin");
        user.setPwd("111");
        userService.login(user);
        model.addAttribute("user", user);
        return "register";
    }
}

Nota: Agregar la anotación @Autowired en UserService hará que se inyecte una instancia de UserService en la instancia de UserController

  1. springmvc-servlet.xml
<!-- 配置包扫描路径,作用自动检测标注Bean -->
<context:component-scan base-package="com.hqyj.cl" />
<mvc:annotation-driven />
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceView">
    <!--前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/" />
    <!--后缀 -->
    <property name="suffix" value=".jsp" />
</bean>
  1. web.xml
<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

  1. índice.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
<h2>Hello World!</h2>
未注册的用户,请
<a href="${pageContext.request.contextPath}/user/register"> 注册</a>!
<br /> 已注册的用户,去
<a href="${pageContext.request.contextPath}/user/login"> 登录</a>!
</body>
</html>
  1. iniciar sesión.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
    登录页面! 欢迎 ${user.name} 登录
</body>
</html>
  1. registro.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
    注册页面!
    注册账号成功,用户名为: ${user.name }
</body>
</html>

Ocho, @ModelAttribute (entender)

La anotación muy importante @ModelAttribute en Spring MVC se usa para vincular los parámetros de solicitud a los objetos del modelo. El objeto modelo se crea antes que el método del controlador, por lo que el método anotado por @ModelAttribute se ejecutará antes de que se ejecute cada método del controlador. usar lo menos posible

1. Propósito

  • aplicado al método
  • aplicado a los parámetros del método
  • Aplicado al método, y el método también usa @RequestMapping

1.1 Aplicado al método

1.1.1 Aplicado a métodos sin valor de retorno

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
    // 方法无返回值
    @ModelAttribute
    public void myModel(@RequestParam(required = false) String name, Model model) {
    
    
        model.addAttribute("name", name);
    }
    @RequestMapping("/index")
    public String model() {
    
    
        return "index";
    }
    
    // 上述代码合二为一
    /*    @RequestMapping("/index")
    public String model(@RequestParam(required = false) String name, Model model) {
        model.addAttribute("name", name);
        return "index";
    }*/
}
  1. índice.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${name}
</body>
</html>

acceso:

​ Usando http://localhost:8080/model/index?name=%E5%BC%A0%E4%B8%89el acceso, la página mostrará el valor correspondiente al nombre. Sugerencia: La cadena después del nombre no son caracteres ilegibles, sino un problema de conversión de cadena. El significado aquí es Zhang San.

1.1.2 Aplicado a métodos con valores de retorno

Con este método, el nombre del objeto de valor devuelto se colocará en el Modelo implícito de forma predeterminada. En el Modelo, la clave es la letra inicial en minúsculas del tipo de valor devuelto, y el valor es el valor devuelto. Equivalente amodel.addAttribute("string", name);

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
     // 方法有返回值
    @ModelAttribute()
    public String myModel(@RequestParam(required = false) String name) {
    
    
        return name;
    }
    @RequestMapping("/index")
    public String model() {
    
    
        return "index";
    }
}
  1. índice.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${string}
</body>
</html>

En circunstancias normales, intente no devolver valores de tipos de datos como cadena, int y flotante en el programa. Use @ModelAttribute para anotar el atributo de valor para personalizar la clave, código de muestra

@ModelAttribute("name")
public String myModel(@RequestParam(required = false) String name) {
    
    
    return name;
}

Equivalente a

model.addAttribute("name", name);

1.2 Aplicado a los parámetros del método

@ModelAttribute se anota en los parámetros del método. Cuando se llama al método, se inyecta el valor del modelo. Esto es muy simple en la práctica y se usa a menudo para asignar atributos de formulario a ** objetos modelo. **

  1. ModelAttributeController
@Controller
@RequestMapping("/model")
public class ModelAttributeController {
    
    
    @RequestMapping("/register")
    public String register(@ModelAttribute("user") User user) {
    
    
        if ("admin".equals(user.getName()) && "111".equals(user.getPwd())) {
    
    
            return "login";
        } else {
    
    
            return "register";
        }
    }
}
  1. iniciar sesión.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
登录页面! 欢迎 ${user.name} 登录
</body>
</html>
  1. índice.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
注册页面!
注册账号成功,用户名为: ${user.name }
</body>
</html>

1.2.1 Descripción

@ModelAttribute("usuario") Usuario La declaración de usuario tiene dos funciones:

  • Encapsule la entrada de parámetros de solicitud en el objeto de usuario
  • Crear una instancia de usuario

Se almacena en el objeto Modelo con "usuario" como valor clave, que tiene la misma función que la instrucción "model.addAttribute("usuario",usuario)". Si no se especifica ningún valor de clave, es decir, "@ModelAttribute User usuario", al crear una instancia de Usuario, "usuario" se almacena como el valor de clave en el objeto Modelo, que tiene la misma función que "model.addAtttribute( declaración "usuario", usuario)".

1.3 ModelAttribute+RequestMapping

  1. ModelAttributeController
@Controller
public class ModelAttributeController {
    
    
    // @ModelAttribute和@RequestMapping同时放在方法上 方法直接返回页面名称 会把类路径拼接到url中
    @RequestMapping("/index")
    @ModelAttribute("name")
    public String model(@RequestParam(required = false) String name) {
    
    
        return name;
    }
}
  1. índice.jsp

    La ruta de la solicitud es http://localhost:8080/j230101SpringMVC_war_exploded/index?name=admin El parámetro de nombre tiene un valor

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    ${name}
</body>
</html

1.3.1 Descripción

Cuando las anotaciones @ModelAttribute y @RequestMapping se aplican a los métodos al mismo tiempo, tienen los siguientes efectos:

  1. El valor de retorno del método se almacenará en el objeto Modelo, y la clave es el valor del atributo de valor de ModelAttribute;
  2. El valor de retorno del método ya no es la ruta de acceso del método, y la ruta de acceso se convertirá en el valor de valor de @RequestMapping, por ejemplo: @RequestMapping(value = “/index”) La página redirigida es index.jsp página;
  3. Cuando use este método, no agregue una ruta de clases, de lo contrario, puede causar errores de ruta.

1.4 La diferencia entre Modelo y ModelAndView

  • Modelo: el parámetro predeterminado que existe en cada solicitud y su método addAttribute() se pueden usar para pasar el valor del servidor a la página del cliente.
  • ModelAndView: contiene dos partes, modelo y vista. Al usarlo, debe crear una instancia usted mismo, usar Model para pasar valores y también puede establecer el nombre de la vista.

1.5 Ejercicios

El método anotado con @ModelAttribute se llamará antes de cada método de procesamiento de solicitudes de la clase del controlador. Esta función se puede utilizar para controlar los permisos de inicio de sesión.

  1. BaseController
public class BaseController {
    
    
    @ModelAttribute
    public void isLogin(HttpSession session) throws Exception {
    
    
        if (session.getAttribute("user") == null) {
    
    
            throw new Exception("没有权限");
        }
    }
}
  1. Controlador de usuario
@RequestMapping("/user")
public class UserController extends BaseController {
    
    
    @RequestMapping("/selectAllUser")
    public String selectAllUser() {
    
    
        return "userList";
    }
}

Nueve, interacción de datos Spring MVC JSON

Spring MVC necesita convertir el formato y el tipo de los datos transmitidos en el proceso de vinculación de datos. Puede convertir datos de tipos como String y otros tipos de datos como JSON. Usamos la tecnología FastJson de Alibaba para implementar Spring MVC para procesar datos en formato JSON. La página necesita introducir jquery. Preste atención al filtrado de recursos (la primera forma). Spring versión 4.0.2 (4.3.13 otras versiones del paquete son demasiado bajas, pero 4.0 no admite el atributo de nombre de requestmaping)

1. Caso

  1. Importar dependencias en el archivo pom.xml (importado antes)
<!-- 格式化对象,方便输出日志 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.1.41</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<!-- jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.6</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.6</version>
</dependency>
  1. El valor de retorno del método JSONController se puede establecer como una colección de mapas
@Controller
@RequestMapping("/json")
public class JSONController {
    
    
    @RequestMapping("/index")
    public String index() {
    
    
        return "index";
    }
    @RequestMapping("/testJson")
    @ResponseBody
    public User testJson(User user) {
    
    
        // 打印接收的 JSON数据
        System.out.println("username=" + user.getUsername() + ",password=" + user.getPassword());
        // 返回JSON格式的响应
        return user;
    }
}
  1. índice.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>测试JSON交互</title>
    <script type="text/javaScript" src="../static/js/jquery-2.1.1.min.js"></script>
</head>
<body>
<form>
    用户名:<input type="text" name="username" id="username"/>
    <br>
    密码:<input type="password" name="password" id="password"/>
    <br>
    <input type="button" value="login" οnclick="login()"/>
</form>
</body>
<script type="text/javaScript">
    function login() {
        $.ajax({
            //请求路径
            url: "../json/testJson",
            //请求类型
            type: "post",
            //定义回调响应的数据格式为JSON字符串,该属性可以省略
            dataType: "json",
            //data表示发送的数据
            data: {
                username: $("#username").val(),
                password: $("#password").val(),
            },
            contentType: "application/x-www-form-urlencoded", //设置请求参数的格式
            processData: true, //设置ajax内部是否自动处理请求参数,默认为true,可省略,如果data给的是个js对象,要么不设置,要么设为true
            //成功响应的结果
            success: function (data) {
                if (data != null) {
                    alert("输入的用户名:" + data.username + ",密码:" + data.password);
                }
            },error:function () {
                alert("服务器错误");
            }
        });
    }
</script>
</html>

2, tipo de contenido

Hay tres tipos comunes de contentType:

// 普通表单提交的数据的格式为application/x-www-form-urlencoded
application/x-www-form-urlencoded
// 发送以ContentType为application/json格式的请求参数,需要把data的内容转为json格式,使用JSON.stringify(param)
application/json
// 上传文件时,请求消息将以multipart/form-data格式封装请求参数
multipart/form-data

// Para enviar parámetros de solicitud con ContentType como aplicación/formato json, debe convertir el contenido de los datos al formato json, use JSON.stringify(param)
application/json

Las variables se pueden definir en ajax

dejar usuario = JSON.stringify({

​ usuario:$(“nombre de usuario”).val(),

​ contraseña:$(“contraseña”).val(),

});

Los siguientes datos: pueden ser modificados a:

datos: usuario; Para pasar al backend, debe usar la anotación @requestBody en los parámetros del método backend para obtener un inicio de sesión público nulo (@requestBodyUser usuario)

10. Interceptor Spring MVC (Interceptor)

​ El Interceptor de Spring MVC es similar al filtro de Java Servlet. Se utiliza principalmente para interceptar las solicitudes de los usuarios y realizar el procesamiento correspondiente. Por lo general, se utiliza en la verificación de autoridad, el registro de información de solicitudes y la evaluación de si los usuarios han iniciado sesión. Y otras funciones.

1. Definir el interceptor

Defina un interceptor, lo implementamos implementando la interfaz HandlerInterceptor

1.1 Caso

  1. Implementar la interfaz HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    
    
        // 获取请求的URL
        String url = request.getRequestURI();
        // login.jsp或登录请求放行,不拦截
        if (url.indexOf("/goLogin") >= 0 || url.indexOf("/login") >= 0) {
    
    
            return true;
        }
        // 获取 session
        HttpSession session = request.getSession();
        Object obj = session.getAttribute("user");
        if (obj != null)
            return true;
        // 没有登录且不是登录页面,转发到登录页面,并给出提示错误信息
        request.setAttribute("msg", "还没登录,请先登录!");
        request.getRequestDispatcher("login").forward(request, response);
        return false;
    }
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
    
    
    }
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
    
    
    }
}

La definición del interceptor implementa la interfaz HandlerInterceptor e implementa los tres métodos en la interfaz, explicados a continuación

  • preHandle(): este método se ejecuta antes que el método de solicitud de procesamiento del controlador, su valor de retorno indica si se debe interrumpir la operación posterior, al devolver verdadero indica que la ejecución continúa hacia abajo y al devolver falso indica que la operación posterior se interrumpe.
  • postHandle( ): este método se ejecuta después de llamar al método de solicitud de procesamiento del controlador y antes de analizar la vista. Este método se puede usar para modificar aún más el modelo y la vista en el dominio de solicitud.
  • afterCompletion(): Este método se ejecuta después de que se ejecuta el método de solicitud de procesamiento del controlador, es decir, se ejecuta después de que se completa el renderizado de la vista.A través de este método, se pueden realizar algunas tareas como la limpieza de recursos y el registro de información de registro.
  1. interceptor de configuración springmvc-servlet.xml
<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <bean class="com.hqyj.cl.utils.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>
  1. Controlador de usuario
@Controller
@RequestMapping("/user")
public class UserController {
    
    
    // 登录页面初始化
    @RequestMapping("/goLogin")
    public String initLogin() {
    
    
        return "login";
    }

    // 处理登录功能
    @RequestMapping("/login")
    public String login(User user, HttpSession session) {
    
    
        if ("admin".equals(user.getUsername()) && "111".equals(user.getPassword())) {
    
    
            // 登录成功,将用户信息保存到session对象中
            session.setAttribute("user", user);
            // 重定向到主页面的跳转方法
            return "redirect:main";
        }
        return "login";
    }

    // 跳转到主页面
    @RequestMapping("/main")
    public String goMain() {
    
    
        return "main";
    }
    
    // 退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
    
    
        // 清除 session
        session.invalidate();
        return "login";
    }
}
  1. iniciar sesión.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>
${ msg }
<form action="../user/login" method="post">
    用户名:<input type="text" name="username" /><br>
    密码:<input type="password" name="password" /><br>
    <input type="submit" value="登录" />
</form>
</body>
</html>
  1. principal.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
欢迎 ${ sessionScope.get("user").username },登录!<br />
<a href="../user/logout">退出</a>
</body>
</html>

11. Carga y descarga de archivos

1. Carga de archivos

  1. Agregue las siguientes dependencias al archivo pom.xml
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.2</version>
</dependency>
  1. springmvc-servlet.xml
<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5000000" />
    <property name="defaultEncoding" value="UTF-8" />
</bean>
  • defaultEncoding: el formato de codificación de la solicitud, el predeterminado es ISO-8859-1, aquí se establece en UTF-8 (Nota: defaultEncoding debe ser consistente con pageEncoding en JSP, para leer el contenido del formulario correctamente).
  • maxUploadSize: el límite superior del tamaño del archivo cargado, en bytes.
  1. envío de formulario fileUpload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
</head>
<body>
    <form action="${pageContext.request.contextPath }/file/upload"
        method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="file"><br> 
        <input type="submit" value="提交">	
    </form>
</body>
</html>
  1. controlador de archivos
@Controller
@RequestMapping("/file")
public class FileController {
    
    
    @RequestMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
    
    
        // 获取上传文件名
        String originalFileName = file.getOriginalFilename();
        // 得到当前的classpath的绝对路径的URI表示法
        String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        int index = rootPath.indexOf("target");
        String path = rootPath.substring(1,index) + "src/main/webapp/static/images/book";
        // 新文件
        File newFile = new File(path,originalFileName);
        // 判断目标文件所在目录是否存在
        if( !newFile.getParentFile().exists()) {
    
    
            // 如果目标文件所在的目录不存在,则创建父目录
            newFile.getParentFile().mkdirs();
        }
        // 将内存中的数据写入磁盘
        file.transferTo(newFile);
        return  "success";
    }
}

1.1 Extensión

Carga de archivos usando ajax

    <form id="uploadForm">
        <input type="file" name="file">
        <br>
        <input type="button" value="button" οnclick="upload()">
    </form>
    <script>
        function upload() {
            var formData = new FormData($("#uploadForm")[0]);
            // 发送ajax请求
            $.ajax({
                url:'/file/upload',
                type:"post",
                data:formData,
                processData : false,  //必须false才会避开jQuery对 formdata 的默认处理
                contentType : false,  //必须false才会自动加上正确的Content-Type
                success:function (data) {
                    console.log(data);
                },error:function () {
                    alert("服务器错误");
                }
            })
        }
    </script>

2. Descarga de archivos

  1. archivoDown.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件下载</title>
</head>
<body>
<form action="/file/down" method="get">
    <input type="submit" value="下载">
</form>
</body>
</html>
  1. controlador de archivos
@RequestMapping("/down")
@ResponseBody
public String down(HttpServletResponse response) throws Exception{
    
    
    // 下载文件的路径
    String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	// 截取到需要的文件存放路径
    int index = rootPath.indexOf("target");
    String path = rootPath.substring(1,index) + "src/main/webapp/static/images/book";
    // 下载文件的名字,假设为banner_1.jpg
    String fileName = "banner_1.jpg";
    //获取输入流
    InputStream is = new BufferedInputStream(new FileInputStream(new File(path,fileName)));
    //转码,免得文件名中文乱码
    String filename = URLEncoder.encode(fileName,"UTF-8");
    //设置文件下载头
    response.addHeader("Content-Disposition", "attachment;filename=" + filename);
    //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
    response.setContentType("multipart/form-data");
    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
    int len = 0;
    while((len = is.read()) != -1){
    
    
        out.write(len);
        out.flush();
    }
    out.close();
    return "success";
}

12. Problema de filtrado de recursos de SpringMVC

**Descripción del problema:** En el archivo web.xml, después de configurar el siguiente código, se interceptarán todas las URL de solicitud, incluidos js, css y otros recursos estáticos, lo que nos impide utilizar estos recursos estáticos.

<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

** Una de las soluciones: **En el archivo springmvc-servlet.xml, agregue el siguiente código

<!-- 默认的注解映射,必须加,不然没办法兼顾二者 -->
<mvc:annotation-driven />
<!--配置静态资源放行 如果web.xml中servlet-name定义为default,则default-servlet-name="default"可以不写-->
<mvc:default-servlet-handler default-servlet-name="default"/>

En el archivo web.xml, agregue el siguiente código

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

**Solución 2: **En el archivo springmvc-servlet.xml, agregue el siguiente código

<?xml version="1.0" encoding="UTF-8"?>
<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:mvc="http://www.springframework.org/schema/mvc"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 包扫描-->
    <context:component-scan base-package="com.hqyj.cl.controller"/>
    <!-- 默认的注解映射,必须加,不然没办法兼顾二者 -->
    <mvc:annotation-driven />
    <mvc:resources mapping="/static/**" location="/static/"/>
	<!-- interceptors -->  
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!-- 不拦截的请求 -->
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="com.hqyj.cl.utils.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--配置视图解析器之InternalResourceViewResolver-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--指定viewclass 必须指定-->
        <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
        <!--前缀-->
        <property name="prefix" value="/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • ubicación: significa que el directorio especificado por ubicación no debe ser interceptado ni solicitado directamente, aquí se refiere a todos los archivos bajo el archivo de recursos en el directorio raíz
  • mapeo: Hace referencia a todos los archivos bajo el archivo de recursos (** representa todos los archivos)

Supongo que te gusta

Origin blog.csdn.net/ailaohuyou211/article/details/130394223
Recomendado
Clasificación