Instrucciones de introducción a Springmvc

1. ¿Qué es SpringMVC?

1. Revisar MVC

1.1 ¿Qué es MVC?
  • MVCEs la abreviatura de modelo ( Model), vista ( View), controlador ( Controller), y es una especificación de diseño de software.

  • Es un método para organizar el código separando la lógica empresarial, los datos y la visualización.

  • MVCLa función principal es reducir el acoplamiento bidireccional entre la vista y la lógica empresarial.

  • MVCNo es un patrón de diseño, MVCes un patrón arquitectónico. MVCPor supuesto que hay diferencias en diferentes

Modelo: el modelo de datos proporciona datos para mostrar, por lo que contiene datos y comportamiento. Puede considerarse como un modelo de dominio o componente JavaBean (que contiene datos y comportamiento), pero ahora generalmente está separado: objeto de valor (datos de datos) y servicio. capa (servicio de comportamiento). Es decir, el modelo proporciona funciones como consulta de datos del modelo y actualización del estado de los datos del modelo, incluidos datos y negocios.
Ver : Responsable de mostrar el modelo, generalmente la interfaz de usuario que vemos y lo que los clientes quieren ver.
Controlador : recibe las solicitudes de los usuarios, las delega al modelo para su procesamiento (cambio de estado) y devuelve los datos del modelo devuelto a la vista después del procesamiento, y la vista es responsable de mostrarlos. En otras palabras, el controlador realiza el trabajo de despachador.
El MVC más típico es el modelo JSP + servlet + javabean.

Insertar descripción de la imagen aquí

1.2 Era del modelo 1
  • En el desarrollo temprano de la web, generalmente elModel1
  • Model1, Dividido principalmente en dos capas, la capa de vista y la capa de modelo.

Insertar descripción de la imagen aquí
Model1Ventajas: la estructura es simple, más adecuada para el desarrollo de proyectos pequeños;
Model1Desventajas: JSPlas responsabilidades no son únicas, las responsabilidades son demasiado pesadas y no es fácil de mantener;

1.3 Era del Modelo 2

Model2Divida un proyecto en tres partes, incluidas vista, control y modelo .
Insertar descripción de la imagen aquí

  1. El usuario envía la solicitud
  2. ServletRecibir datos de solicitud y llamar al método de lógica empresarial correspondiente.
  3. Una vez completado el procesamiento comercial, los datos actualizados se devuelven aServlet
  4. ServletDirección JSP, página de representación JSPde origen
  5. Responda a la página actualizada en el front-end

Análisis de responsabilidad:
Controlador: capa de control

  1. Obtener datos del formulario
  2. Llame a la lógica empresarial
  3. Ir a la página especificada

Modelo: modelo

  1. Lógica de negocios
  2. El estado de los datos guardados.

Ver: ver

  1. mostrar página

Model2Esto no solo mejora la tasa de reutilización del código y la escalabilidad del proyecto, sino que también reduce en gran medida el costo de mantenimiento del proyecto. Model1La implementación del modo es relativamente simple y adecuada para el desarrollo rápido de proyectos a pequeña escala.La página intermedia desempeña dos funciones, mezclando lógica de control y Model1lógica de rendimiento , lo que da como resultado una reutilización de código muy baja y aumenta la complejidad de la expansión y el mantenimiento de la aplicación. Dificultad. deficiencias eliminadas .JSPViewControllerModel2Model1

1.4 Revisar servlet
  1. ¡ Crea un nuevo Mavenproyecto como proyecto principal! pom¡confiar!
<dependencies>
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.12</version>
   </dependency>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-webmvc</artifactId>
       <version>5.1.9.RELEASE</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.5</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet.jsp</groupId>
       <artifactId>jsp-api</artifactId>
       <version>2.2</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>jstl</artifactId>
       <version>1.2</version>
   </dependency>
</dependencies>
  1. Construye un Moudle: springmvc-01-servlet¡ Web appsoporte agregado!
  2. Importación servlety jspdependencias jar_
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
</dependency>
<dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.2</version>
</dependency>
  1. Escribe una Servletclase para manejar las solicitudes de los usuarios.
package com.kuang.servlet;//实现Servlet接口
public class HelloServlet extends HttpServlet {
    
    
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
       //取得参数
       String method = req.getParameter("method");
       if (method.equals("add")){
    
    
           req.getSession().setAttribute("msg","执行了add方法");
      }
       if (method.equals("delete")){
    
    
           req.getSession().setAttribute("msg","执行了delete方法");
      }
       //业务逻辑
       //视图跳转
       req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);
  }@Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
       doGet(req,resp);
  }
}

Escriba hello.jsp, cree una nueva carpeta jsp en el directorio WEB-INF y cree un nuevo hello.jsp

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

Registrar servlet en web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
   <servlet>
       <servlet-name>HelloServlet</servlet-name>
       <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>HelloServlet</servlet-name>
       <url-pattern>/user</url-pattern>
   </servlet-mapping></web-app>

Configure Tomcat y comience a probar

  • localhost:8080/usuario?método=añadir
  • localhost:8080/usuario?método=añadir

¿Qué hace el marco MVC?

  • Se urlasignará a javauna clase o javamétodo de una clase.
  • Encapsular datos enviados por usuarios
  • Procesar la solicitud – llamar al procesamiento comercial relacionado – encapsular los datos de respuesta
  • Renderizar los datos de respuesta . jsp / htmly otros datos de la capa de presentación.

Nota:
Los marcos MVC comunes del lado del servidor incluyen: Struts, Spring MVC, ASP.NET MVC, Zend Framework, JSF; marcos MVC frontales comunes: vue, angularjs, react, backbone; otros modelos han evolucionado a partir de MVC, como por ejemplo: MVP , MVVM, etc.

2. ¿Qué es SpringMVC?

2.1 Descripción general

Insertar descripción de la imagen aquí

Spring MVCSpring Framework, es un marco ligero basado en Javala implementación .MVCWeb

Vea la documentación oficial : https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web

¿Por qué deberíamos aprender SpringMVC?

Características de Spring MVC:

  • Ligero y fácil de aprender.
  • MVCMarco eficiente basado en solicitudes y respuestas
  • Buena compatibilidad e Springintegración perfecta
  • Convención sobre configuración
  • Potentes funciones: RESTfulvalidación de datos, formato, localización, temas, etc.
  • Sencillo y flexible

El marco web de Spring está diseñado en torno a DispatcherServlet [Scheduling Servlet].

La función de DispatcherServlet es distribuir solicitudes a diferentes procesadores. A partir de Spring 2.5, los usuarios que usan Java 5 o superior pueden desarrollar en base a anotaciones, lo cual es muy simple;

Precisamente porque SpringMVC es bueno, simple, conveniente, fácil de aprender y naturalmente se integra perfectamente con Spring (usando SpringIoC y Aop), la convención de uso es mejor que la configuración. Puede realizar pruebas junit simples. Es compatible con el estilo Restful. Manejo de excepciones, localización. e internacionalización, validación de datos, conversión de tipos, interceptores, etc. Entonces tenemos que aprender;

Lo más importante es que hay mucha gente y empresas usándolo;

2.2 Controlador central

El marco web de Spring está diseñado en torno a DispatcherServlet. La función de DispatcherServlet es distribuir solicitudes a diferentes procesadores. A partir de Spring 2.5, los usuarios que usan Java 5 o superior pueden usar una declaración de controlador basada en anotaciones.

El marco Spring MVC, como muchos otros marcos MVC, está controlado por solicitudes, envía solicitudes y proporciona otras funciones alrededor de un servlet central. DispatcherServlet es un servlet real (hereda de la clase base HttpServlet).

Insertar descripción de la imagen aquí

El principio de SpringMVC se muestra en la siguiente figura:

Cuando se inicia una solicitud, la solicitud es interceptada por el controlador anterior, se genera una solicitud de proxy basada en los parámetros de la solicitud, se encuentra el controlador real correspondiente a la solicitud, el controlador procesa la solicitud, crea un modelo de datos y accede a la base de datos. , responde al modelo al controlador central y controla El procesador usa el modelo y la vista para representar los resultados de la vista, devuelve los resultados al controlador central y luego devuelve los resultados al solicitante.

Insertar descripción de la imagen aquí

Versión china

Insertar descripción de la imagen aquí

2.3 Principio de ejecución de SpringMVC

Insertar descripción de la imagen aquí

La imagen muestra un diagrama de flujo más completo de SpringMVC: la línea continua indica la tecnología proporcionada por el marco SpringMVC, que no requiere que los desarrolladores la implementen, y la línea de puntos indica que requiere que los desarrolladores la implementen.

Analice brevemente el proceso de ejecución:

DispatcherServlet representa el controlador frontal y es el centro de control de todo SpringMVC. El usuario realiza una solicitud y DispatcherServlet la recibe y la intercepta.

Suponemos que la URL solicitada es:http://localhost:8080/SpringMVC/hello

La URL anterior se divide en tres partes:

http://localhost:8080 representa el nombre de dominio del servidor

SpringMVC representa un sitio web implementado en el servidor

hola significa controlador

A través del análisis, la URL anterior se expresa como: solicitando el controlador de saludo del sitio SpringMVC ubicado en el servidor localhost:8080.

  1. HandlerMapping es un mapeo de procesador. DispatcherServlet llama a HandlerMapping y HandlerMapping busca a Handler de acuerdo con la URL de solicitud.
  2. HandlerExecution representa un controlador específico. Su función principal es encontrar el controlador en función de la URL. Como se muestra arriba, la URL a buscar para el controlador es: hola.
  3. HandlerExecution pasa la información analizada a DispatcherServlet, como el análisis de la asignación del controlador, etc.
  4. HandlerAdapter representa el adaptador de procesador, que ejecuta Handler de acuerdo con reglas específicas.
  5. El controlador permite que se ejecute un controlador específico.
  6. El controlador devuelve información de ejecución específica a HandlerAdapter, como ModelAndView.
  7. HandlerAdapter pasa el nombre lógico o modelo de la vista a DispatcherServlet.
  8. DispatcherServlet llama al solucionador de vistas (ViewResolver) para resolver el nombre de la vista lógica pasado por HandlerAdapter.
  9. El solucionador de vistas pasa el nombre de la vista lógica resuelta a DispatcherServlet.
  10. DispatcherServlet llama a vistas específicas en función de los resultados de la vista analizados por el analizador de vistas.
  11. La vista final se presenta al usuario.

Escuchemos el principio aquí primero. No importa si no lo comprende. Escribiremos el código correspondiente para implementarlo y todos lo entenderán. Si no lo comprende, simplemente escríbalo 10 veces. ¡No hay gente estúpida, sólo gente vaga!

2. El primer programa MVC

Hola, SpringMVC

En la sección anterior, explicamos qué es SpringMVC y cómo funciona.

¡Ahora echemos un vistazo a cómo usar SpringMVC rápidamente para escribir nuestro programa!

1. Versión de configuración

1. Cree un nuevo Moudle, springmvc-02-hellomvc, y agregue soporte web.

2. ¡Asegúrese de haber importado las dependencias de SpringMVC!

3. Configure web.xml y registre DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0"><!--1.注册DispatcherServlet-->
   <servlet>
       <servlet-name>springmvc</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!--启动级别-1-->
       <load-on-startup>1</load-on-startup>
   </servlet><!--/ 匹配所有的请求;(不包括.jsp)-->
   <!--/* 匹配所有的请求;(包括.jsp)-->
   <servlet-mapping>
       <servlet-name>springmvc</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
   
</web-app>

4. ¡Escriba el archivo de configuración SpringMVC! Nombre: springmvc-servlet.xml: [servletname]-servlet.xml
Descripción, los requisitos de nombre aquí se basan en los oficiales. Aquí está: 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"></beans>

5. Agregar asignador de procesamiento

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

6. Agregar adaptador de procesador

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

7. Agregar analizador de vistas

<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
   <!--前缀-->
   <property name="prefix" value="/WEB-INF/jsp/"/>
   <!--后缀-->
   <property name="suffix" value=".jsp"/>
</bean>

8. Para escribir el Controlador comercial que queremos operar, debemos implementar la interfaz del Controlador o agregar anotaciones, necesitamos devolver un ModelAndView, cargar los datos y sellar la vista;

package com.kuang.controller;

import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.Controller;

//注意:这里我们先导入Controller接口
public class HelloController implements Controller {
    
    
 
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();
 
        //封装对象,放在ModelAndView中。Model
        mv.addObject("msg","HelloSpringMVC!");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

9. Envíe su clase al contenedor SpringIOC y registre el bean.

<!--Handler--><bean id="/hello" class="com.kuang.controller.HelloController"/>

10. Escriba la página jsp a saltar para mostrar los datos almacenados en ModellandView y nuestra página normal;

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

11. ¡Configure Tomcat para comenzar a probar!

http://localhost:8080/hola

La página muestra: ¡HolaSpringMVC!

Posibles problemas: aparece 404 durante el acceso, pasos para solucionar el problema:

  • Verifique la salida de la consola para ver si falta algún paquete jar.
  • Si el paquete jar existe y muestra que no se puede generar, agregue la dependencia lib en la versión del proyecto de IDEA.
  • ¡Reinicie Tomcat para resolver el problema!

Insertar descripción de la imagen aquí

Resumen: Al observar esto, creo que la mayoría de los estudiantes pueden entender el principio, pero no lo escribiríamos así en el desarrollo real, de lo contrario estaríamos locos, ¿por qué deberíamos aprender esto? Echemos un vistazo a una implementación de versión anotada. Esta es la esencia de SpringMVC. Solo mire esta imagen para ver lo simple que es.

2. Versión comentada

1. Cree un nuevo Moudle, springmvc-03-hello-annotation. ¡Agregue soporte web!

2. Dado que Maven puede tener problemas de filtrado de recursos, mejoraremos la configuración.

<build>
   <resources>
       <resource>
           <directory>src/main/java</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
       <resource>
           <directory>src/main/resources</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
   </resources>
</build>

3. Introduzca las dependencias relevantes en el archivo pom.xml: principalmente la biblioteca central de Spring framework, Spring MVC, servlet, JSTL, etc. Lo hemos introducido en la dependencia principal.

4. Configurar web.xml

punto importante:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
 
   <!--1.注册servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- 启动顺序,数字越小,启动越早 -->
       <load-on-startup>1</load-on-startup>
   </servlet>
 
   <!--所有请求都会被springmvc拦截 -->
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
 
</web-app>

La diferencia entre / y /*:

  • < url-pattern > / </ url-pattern > no coincidirá con .jsp, solo para la solicitud que escribimos, es decir: .jsp no ingresará a la clase DispatcherServlet de Spring.
  • <url-pattern> /*</url-pattern> coincidirá con *.jsp. Al regresar a la vista jsp, ingresará nuevamente a la clase DispatcherServlet de Spring, lo que provocará que no se encuentre el controlador correspondiente y se informe un error 404.
  • Preste atención al problema de la versión web.xml, ¡necesita la última versión!
  • Registrar DispatcherServlet
  • Archivo de configuración SpringMVC asociado
  • Nivel de inicio 1
  • La ruta de mapeo es / [No use /*, causará 404]

5. Agregue el archivo de configuración Spring MVC

Agregue el archivo de configuración springmvc-servlet.xml en el directorio de recursos. El formulario de configuración es básicamente similar a la configuración del contenedor Spring. Para admitir IOC basado en anotaciones, se configura la función de escaneo automático de paquetes. La información de configuración específica es como sigue:

6. Agregue el archivo de configuración Spring MVC

<?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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.kuang.controller"/>
    <!-- 让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />
    <!--
  支持mvc注解驱动
      在spring中一般采用@RequestMapping注解来完成映射关系
      要想使@RequestMapping注解生效
      必须向上下文中注册DefaultAnnotationHandlerMapping
      和一个AnnotationMethodHandlerAdapter实例
      这两个实例分别在类级别和方法级别处理。
      而annotation-driven配置帮助我们自动完成上述两个实例的注入。
   -->
    <mvc:annotation-driven/>
 
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

En el analizador de vistas, almacenamos todas las vistas en el directorio /WEB-INF/, lo que garantiza la seguridad de las vistas, porque el cliente no puede acceder directamente a los archivos de este directorio.

  • Dejar que las anotaciones del COI entren en vigor
  • Filtrado de recursos estáticos: HTML, JS, CSS, imágenes, vídeos…
  • Controlador de anotaciones MVC
  • Configurar la resolución de vistas

7. Crear controlador

Escriba una clase de control Java: com.kuang.controller.HelloController, preste atención a los estándares de codificación

package com.kuang.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class HelloController {
    
    
    @RequestMapping("/hello")
    public String hello(Model model){
    
    
        //封装数据
        model.addAttribute("msg","hello,springmvcAnnotation");
        return "hello";
    }
} 
  • @Controller sirve para escanear automáticamente el contenedor Spring IOC cuando se inicializa;
  • @RequestMapping es mapear la ruta de la solicitud. Debido a que hay mapeos en clases y métodos, el acceso debe ser /HelloController/hello;
  • El parámetro de tipo de Modelo se declara en el método para llevar los datos de la Acción a la vista;
  • El resultado devuelto por el método es el nombre de la vista hola, más el sufijo en el archivo de configuración para convertirse en WEB-INF/jsp/hello.jsp.

8. Crea una capa de vista

Cree hello.jsp en el directorio WEB-INF/jsp. La vista puede extraer y mostrar directamente la información recuperada del Controlador;

El valor u objeto almacenado en el Modelo se puede recuperar mediante representación EL;

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

3. Configure Tomcat para ejecutar
Configure Tomcat, inicie el servidor, acceda a la ruta de solicitud correspondiente
Insertar descripción de la imagen aquí
y ejecútelo correctamente.

3. Resumen

Los pasos de implementación son realmente muy simples:

  1. Crear un nuevo proyecto web
  2. Importar paquetes jar relacionados
  3. Escriba web.xml y registre DispatcherServlet
  4. Escribir el archivo de configuración springmvc
  5. El siguiente paso es crear la clase de control correspondiente, controlador
  6. Finalmente, se mejora la correspondencia entre la vista frontal y el controlador.
  7. Ejecución de prueba de depuración.

Tres piezas principales que deben configurarse para usar springMVC:

Mapeador de procesador, adaptador de procesador, resolución de vista

Por lo general, solo necesitamos configurar manualmente el analizador de vistas , y el asignador del procesador y el adaptador del procesador solo necesitan habilitar el controlador de anotaciones, lo que elimina la necesidad de grandes secciones de configuración xml.

Repasemos el principio nuevamente ~

Insertar descripción de la imagen aquí
¡A continuación vamos a estudiar los estilos Controller y RestFul!

3. Descanso y controlador

ControladorControlador

¡En la sección anterior, escribimos nuestro primer programa SpringMVC!

¡Ahora echemos un vistazo al contenido específico del controlador y la solicitud de ruta interna!

1. ControladorControlador

  • El controlador es responsable de proporcionar acceso al comportamiento de la aplicación, generalmente a través de la definición de interfaz o la definición de anotaciones.
  • El controlador es responsable de analizar la solicitud del usuario y convertirla en un modelo.
  • En Spring MVC una clase de controlador puede contener múltiples métodos
  • En Spring MVC, hay muchas formas de configurar el controlador

2. Implementar la interfaz del Controlador

El controlador es una interfaz. En el paquete org.springframework.web.servlet.mvc, solo hay un método en la interfaz;

//实现该接口的类获得控制器功能
public interface Controller {
    
    
   //处理请求且返回一个模型与视图对象
   ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}

prueba

  1. Cree un nuevo Moudle, springmvc-04-controller. ¡Haga una copia de 03 ahora mismo y procedamos!
    1. Eliminar HolaController
    2. ¡El archivo de configuración mvc solo sale del solucionador de vistas!
  2. Escribe una clase de controlador, ControllerTest1
//定义控制器
//注意点:不要导错包,实现Controller接口,重写方法;
public class ControllerTest1 implements Controller {
    
    
 
   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","Test1Controller");
       mv.setViewName("test");
       return mv;
  }
}
  1. Después de escribir, registre el bean solicitado en el archivo de configuración de Spring; el nombre corresponde a la ruta de la solicitud y la clase corresponde a la clase que maneja la solicitud.
<bean name="/t1" class="com.kuang.controller.ControllerTest1"/>
  1. Escriba el front-end test.jsp, preste atención para escribirlo en el directorio WEB-INF/jsp, correspondiente a nuestro analizador de vistas.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Kuangshen</title>
</head>
<body>
${msg}
</body>
</html>
  1. Configure Tomcat para ejecutar la prueba. No tengo un nombre de versión del proyecto aquí. Lo configuro con /, por lo que no necesito agregar un nombre de proyecto a la solicitud. ¡OK!

Insertar descripción de la imagen aquí
ilustrar:

  • Implementar la interfaz Controlador para definir un controlador es un enfoque más antiguo
  • La desventaja es: solo hay un método en un controlador. Si desea varios métodos, debe definir varios controladores, y el método de definición es más problemático;

3. Utilice la anotación @Controller

  • El tipo de anotación @Controller se utiliza para declarar que una instancia de la clase Spring es un controlador (también se mencionaron otras tres anotaciones cuando se habla de IOC);
  • Spring puede usar el mecanismo de escaneo para encontrar todas las clases de controlador basadas en anotaciones en la aplicación. Para garantizar que Spring pueda encontrar su controlador, el escaneo de componentes debe declararse en el archivo de configuración.
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="com.kuang.controller"/>
  • Agregue una clase ControllerTest2 y use anotaciones para implementarla;
//@Controller注解的类会自动添加到Spring上下文中
@Controller
public class ControllerTest2{
    
    
 
   //映射访问路径
   @RequestMapping("/t2")
   public String index(Model model){
    
    
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "ControllerTest2");
       //返回视图位置
       return "test";
  }
 
}
  • Ejecute la prueba de Tomcat

Insertar descripción de la imagen aquí

Se puede encontrar que nuestras dos solicitudes pueden apuntar a una vista, pero los resultados de la página son diferentes. De esto podemos ver que la vista se reutiliza y existe una relación de acoplamiento débil entre el controlador y la vista.

¡El método de anotación es el método más utilizado!

4. Solicitar mapeo

  • La anotación @RequestMapping se utiliza para asignar la URL a una clase de controlador o a un método de controlador específico. Se puede utilizar en clases o métodos. Usado en una clase, significa que todos los métodos de la clase que responden a las solicitudes usan esta dirección como ruta principal.
  • Para probar la conclusión con mayor precisión, podemos agregar un nombre de proyecto para probar myweb.
  • Solo anótelo en el método.
@Controller
public class TestController {
    
    
   @RequestMapping("/h1")
   public String test(){
    
    
       return "test";
  }
}

Ruta de acceso:http://localhost:8080 / 项目名 / h1

  • Anotar clases y métodos simultáneamente.
@Controller
@RequestMapping("/admin")
public class TestController {
    
    
   @RequestMapping("/h1")
   public String test(){
    
    
       return "test";
  }
}

Ruta de acceso: http://localhost:8080 / 项目名/ admin /h1primero debe especificar la ruta de clase y luego la ruta del método;

5. Estilo descansado

concepto

Restful es un estilo de posicionamiento y operación de recursos. No es una norma ni un protocolo, sólo un estilo. El software diseñado en base a este estilo puede ser más simple, más jerárquico y más fácil de implementar mecanismos como el almacenamiento en caché.

Función

Recursos: todo lo que hay en Internet se puede resumir en recursos.

Operaciones de recursos: utilice POST, DELETE, PUT, GET y utilice diferentes métodos para operar recursos.

Correspondiente a agregar, eliminar, modificar y consultar respectivamente.

Manipula los recursos de la forma tradicional : ¡consigue diferentes efectos a través de diferentes parámetros! Método único, publicar y obtener

  • http://127.0.0.1/item/queryItem.action?id=1Consulta, OBTENER
  • http://127.0.0.1/item/saveItem.actionNueva publicación
  • http://127.0.0.1/item/updateItem.actionactualizar, publicar
  • http://127.0.0.1/item/deleteItem.action?id=1Eliminar, OBTENER o PUBLICAR

Utilice RESTful para operar recursos : ¡se pueden lograr diferentes efectos a través de diferentes métodos de solicitud! De la siguiente manera: ¡La dirección de solicitud es la misma, pero las funciones pueden ser diferentes!

  • http://127.0.0.1/item/1Consulta, OBTENER
  • http://127.0.0.1/itemNueva publicación
  • http://127.0.0.1/itemactualizar,PONER
  • http://127.0.0.1/item/1borrar,BORRAR

prueba de estudio

  1. Crea una nueva clase RestFulController
@Controller
public class RestFulController {
    
    
}
  1. En Spring MVC, puede usar la anotación @PathVariable para vincular el valor del parámetro del método a una variable de plantilla URI.
@Controller
public class RestFulController {
    
    
 
   //映射访问路径
   @RequestMapping("/commit/{p1}/{p2}")
   public String index(@PathVariable int p1, @PathVariable int p2, Model model){
    
    
       
       int result = p1+p2;
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "结果:"+result);
       //返回视图位置
       return "test";
       
  }
   
}
  1. Probemos la solicitud y comprobemos

  2. Pensamiento: ¿Cuáles son los beneficios de utilizar variables de ruta?

    1. Simplifique los caminos;
    2. Es más conveniente obtener parámetros y el marco realizará automáticamente la conversión de tipos.
    3. Los parámetros de acceso pueden restringirse por el tipo de variable de ruta. Si los tipos son diferentes, no se puede acceder al método de solicitud correspondiente. Por ejemplo, la ruta a la que se accede aquí es /commit/1/a, entonces la ruta no coincide con el método y no será un parámetro. La conversión falló.
  3. Modifiquemos el tipo de parámetro correspondiente y probemos nuevamente.

//映射访问路径
@RequestMapping("/commit/{p1}/{p2}")
public String index(@PathVariable int p1, @PathVariable String p2, Model model){
    
    
 
   String result = p1+p2;
   //Spring MVC会自动实例化一个Model对象用于向视图中传值
   model.addAttribute("msg", "结果:"+result);
   //返回视图位置
   return "test";
 
}

Utilice el atributo de método para especificar el tipo de solicitud

Se utiliza para restringir el tipo de solicitud y limitar el alcance de la solicitud. Especifique el tipo de predicado de solicitud, como GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE, etc.

Probémoslo:

  • Agregar un método
//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {
    
    RequestMethod.POST})
public String index2(Model model){
    
    
   model.addAttribute("msg", "hello!");
   return "test";
}
  • Cuando utilizamos la barra de direcciones del navegador para acceder, el valor predeterminado es Obtener solicitud, que informará el error 405:

Insertar descripción de la imagen aquí

  • Si cambia POST a GET, será normal;
//映射访问路径,必须是Get请求
@RequestMapping(value = "/hello",method = {
    
    RequestMethod.GET})
public String index2(Model model){
    
    
   model.addAttribute("msg", "hello!");
   return "test";
}

Insertar descripción de la imagen aquí
resumen:

La anotación @RequestMapping de Spring MVC puede manejar métodos de solicitud HTTP, como GET, PUT, POST, DELETE y PATCH.

Todas las solicitudes de la barra de direcciones serán del tipo HTTP GET de forma predeterminada.

Las variantes de anotaciones a nivel de método son las siguientes: Anotaciones combinadas

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

@GetMapping es una anotación combinada que se usa comúnmente.

Actúa como un atajo para @RequestMapping(método =RequestMethod.GET).

Extensión: Método de depuración del pequeño pato amarillo

Escenario 1: Todos hemos tenido la experiencia de preguntar y explicar problemas de programación a otros (quizás incluso a personas que no saben nada de programación), sin embargo, muchas veces pensamos en la solución del problema mientras explicamos. lo hace, y luego la otra persona no lo hace. Una mirada confusa en su rostro.

Escenario 2: Tu colega viene a hacerte una pregunta, pero cuando termina de responder la pregunta, o se le ocurre la respuesta en medio de la conversación, te deja con una mirada confusa.

De hecho, los dos fenómenos de escena anteriores son la llamada depuración del pato de goma, también conocida como depuración del pato de goma y uno de los métodos de depuración más utilizados en nuestra ingeniería de software.

Insertar descripción de la imagen aquí

4. Procesamiento de datos y salto.

¡Ahora echemos un vistazo al procesamiento de recepción de parámetros de SpringMVC y al procesamiento de salto de resultados!

1. Método de salto de resultados

1.1 Modelo y vista

Configure el objeto ModelAndView, según el nombre de la vista, y el solucionador de vista para saltar a la página especificada.

Página: {ver prefijo de resolución} + verNombre + {ver sufijo de resolución}

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     id="internalResourceViewResolver">
   <!-- 前缀 -->
   <property name="prefix" value="/WEB-INF/jsp/" />
   <!-- 后缀 -->
   <property name="suffix" value=".jsp" />
</bean>

Clase de controlador correspondiente

public class ControllerTest1 implements Controller {
    
    
 
   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}
1.2 API de servlet

Al configurar ServletAPI, no se requiere resolución de vista.

  1. Salida a través de HttpServletResponse
  2. Redirigir a través de HttpServletResponse
  3. Reenvío a través de HttpServletResponse
@Controller
public class ResultGo {
    
    
 
   @RequestMapping("/result/t1")
   public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
    
    
       rsp.getWriter().println("Hello,Spring BY servlet API");
  }
 
   @RequestMapping("/result/t2")
   public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
    
    
       rsp.sendRedirect("/index.jsp");
  }
 
   @RequestMapping("/result/t3")
   public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
    
    
       //转发
       req.setAttribute("msg","/result/t3");
       req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
  }
 
}
1.3 primaveraMVC

El reenvío y la redirección se implementan a través de SpringMVC; no se requiere resolución de vista;

Antes de realizar la prueba, debe comentar el solucionador de vistas.

@Controller
public class ResultSpringMVC {
    
    
   @RequestMapping("/rsm/t1")
   public String test1(){
    
    
       //转发
       return "/index.jsp";
  }
 
   @RequestMapping("/rsm/t2")
   public String test2(){
    
    
       //转发二
       return "forward:/index.jsp";
  }
 
   @RequestMapping("/rsm/t3")
   public String test3(){
    
    
       //重定向
       return "redirect:/index.jsp";
  }
}

El reenvío y la redirección se implementan a través de SpringMVC, con resolución de vista;

La redirección no requiere resolución de vistas, la esencia es volver a solicitar un nuevo lugar, así que preste atención al problema de la ruta.

Puede redirigir a otra implementación de solicitud.

@Controller
public class ResultSpringMVC2 {
    
    
   @RequestMapping("/rsm2/t1")
   public String test1(){
    
    
       //转发
       return "test";
  }
 
   @RequestMapping("/rsm2/t2")
   public String test2(){
    
    
       //重定向
       return "redirect:/index.jsp";
       //return "redirect:hello.do"; //hello.do为另一个请求/
  }
 
}

2. Procesamiento de datos

2.1 Procesamiento de los datos enviados

1. El nombre de dominio enviado es coherente con el nombre del parámetro del método de procesamiento.

enviar datos:http://localhost:8080/hello?name=kuangshen

Acercarse :

@RequestMapping("/hello")
public String hello(String name){
    
    
   System.out.println(name);
   return "hello";
}

Salida de fondo: kuangshen

2. El nombre de dominio enviado no coincide con el nombre del parámetro del método de procesamiento.

enviar datos:http://localhost:8080/hello?username=kuangshen

Acercarse :

//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
    
    
   System.out.println(name);
   return "hello";
}

Salida de fondo: kuangshen

3. Lo que se envía es un objeto.

Se requiere que el campo del formulario enviado tenga el mismo nombre de atributo que el objeto, y el objeto se puede utilizar como parámetro.

1. clase de entidad

public class User {
    
    
   private int id;
   private String name;
   private int age;
   //构造
   //get/set
   //tostring()
}

2. Enviar datos: http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

3. Método de tratamiento:

@RequestMapping("/user")
public String user(User user){
    
    
   System.out.println(user);
   return "hello";
}

Salida en segundo plano: Usuario {id=1, nombre='kuangshen', edad=15}

Nota: Si se utiliza un objeto, el nombre del parámetro pasado por la interfaz debe ser coherente con el nombre del objeto; de lo contrario, será nulo.

2.2 Los datos se muestran en la interfaz

El primero: a través de ModelAndView

Este siempre ha sido el caso antes, no explicaré demasiado.

public class ControllerTest1 implements Controller {
    
    
 
   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}

Segundo tipo: a través de ModelMap

ModeloMapa

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
    
    
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("name",name);
   System.out.println(name);
   return "hello";
}

El tercer tipo: a través del modelo.

Modelo

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
    
    
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("msg",name);
   System.out.println(name);
   return "test";
}
2.3 Comparación

En términos simples para principiantes, la diferencia es:

Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
 
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
 
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

Por supuesto, un mayor desarrollo futuro considerará el rendimiento y la optimización, y no podemos limitar nuestra comprensión a esto.

Utilice el 80% de su tiempo para sentar una base sólida, el 18% restante de su tiempo para estudiar el marco y el 2% de su tiempo para aprender algo de inglés. La documentación oficial del marco es siempre el mejor tutorial.

2.4 Problema de código confuso

Pasos de prueba:

1. Podemos escribir un formulario de envío en la página de inicio.

<form action="/e/t" method="post">
 <input type="text" name="name">
 <input type="submit">
</form>

2. Escriba la clase de procesamiento correspondiente en segundo plano.

@Controller
public class Encoding {
    
    
   @RequestMapping("/e/t")
   public String test(Model model,String name){
    
    
       model.addAttribute("msg",name); //获取表单提交的值
       return "test"; //跳转到test页面显示输入的值
  }
}

3. Ingrese chino para probar y encontrar caracteres confusos.

Debo decir que el problema del código confuso es un problema muy común en nuestro desarrollo, ¡y también es un dolor de cabeza para nosotros los programadores!

En el pasado, el problema de los caracteres confusos se resolvía mediante filtros, pero SpringMVC nos proporciona un filtro que se puede configurar en web.xml.

¡Modificó el archivo xml y necesita reiniciar el servidor!

<filter>
   <filter-name>encoding</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
       <param-name>encoding</param-name>
       <param-value>utf-8</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>encoding</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Pero descubrimos que, en algunos casos extremos, este filtro no ayuda a mejorar.

Acercarse :

1. Modifique el archivo de configuración de Tomcat: ¡establezca la codificación!

<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          redirectPort="8443" />

2. Filtros personalizados

package com.kuang.filter;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
 
/**
* 解决get和post请求 全部乱码的过滤器
*/
public class GenericEncodingFilter implements Filter {
    
    
 
   @Override
   public void destroy() {
    
    
  }
 
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
       //处理response的字符编码
       HttpServletResponse myResponse=(HttpServletResponse) response;
       myResponse.setContentType("text/html;charset=UTF-8");
 
       // 转型为与协议相关对象
       HttpServletRequest httpServletRequest = (HttpServletRequest) request;
       // 对request包装增强
       HttpServletRequest myrequest = new MyRequest(httpServletRequest);
       chain.doFilter(myrequest, response);
  }
 
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
    
    
  }
 
}
 
//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {
    
    
 
   private HttpServletRequest request;
   //是否编码的标记
   private boolean hasEncode;
   //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
   public MyRequest(HttpServletRequest request) {
    
    
       super(request);// super必须写
       this.request = request;
  }
 
   // 对需要增强方法 进行覆盖
   @Override
   public Map getParameterMap() {
    
    
       // 先获得请求方式
       String method = request.getMethod();
       if (method.equalsIgnoreCase("post")) {
    
    
           // post请求
           try {
    
    
               // 处理post乱码
               request.setCharacterEncoding("utf-8");
               return request.getParameterMap();
          } catch (UnsupportedEncodingException e) {
    
    
               e.printStackTrace();
          }
      } else if (method.equalsIgnoreCase("get")) {
    
    
           // get请求
           Map<String, String[]> parameterMap = request.getParameterMap();
           if (!hasEncode) {
    
     // 确保get手动编码逻辑只运行一次
               for (String parameterName : parameterMap.keySet()) {
    
    
                   String[] values = parameterMap.get(parameterName);
                   if (values != null) {
    
    
                       for (int i = 0; i < values.length; i++) {
    
    
                           try {
    
    
                               // 处理get乱码
                               values[i] = new String(values[i]
                                      .getBytes("ISO-8859-1"), "utf-8");
                          } catch (UnsupportedEncodingException e) {
    
    
                               e.printStackTrace();
                          }
                      }
                  }
              }
               hasEncode = true;
          }
           return parameterMap;
      }
       return super.getParameterMap();
  }
 
   //取一个值
   @Override
   public String getParameter(String name) {
    
    
       Map<String, String[]> parameterMap = getParameterMap();
       String[] values = parameterMap.get(name);
       if (values == null) {
    
    
           return null;
      }
       return values[0]; // 取回参数的第一个值
  }
 
   //取所有值
   @Override
   public String[] getParameterValues(String name) {
    
    
       Map<String, String[]> parameterMap = getParameterMap();
       String[] values = parameterMap.get(name);
       return values;
  }
}

Esto también está escrito por algunos expertos que encontré en línea. En circunstancias normales, el procesamiento confuso predeterminado de SpringMVC ya puede resolverlo muy bien.

¡Entonces configure este filtro en web.xml!

El problema de los caracteres confusos requiere más atención: siempre que sea posible, la codificación debe establecerse en la codificación unificada UTF-8.

5. Integrar el marco del MUS

1. Requisitos medioambientales

ambiente:

  • IDEA
  • MySQL 5.7.19
  • Gato 9
  • Maven 3.6

Requerir:

  • Es necesario dominar la base de datos MySQL, conocimientos de Spring, JavaWeb y MyBatis y conocimientos simples de front-end;

2. Entorno de base de datos

Crear una tabla de base de datos para almacenar datos de libros

CREATE DATABASE `ssmbuild`;
 
USE `ssmbuild`;
 
DROP TABLE IF EXISTS `books`;
 
CREATE TABLE `books` (
`bookID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '书id',
`bookName` VARCHAR(100) NOT NULL COMMENT '书名',
`bookCounts` INT(11) NOT NULL COMMENT '数量',
`detail` VARCHAR(200) NOT NULL COMMENT '描述',
KEY `bookID` (`bookID`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
 
INSERT  INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES
(1,'Java',1,'从入门到放弃'),
(2,'MySQL',10,'从删库到跑路'),
(3,'Linux',5,'从进门到进牢');

3. Configuración básica del entorno

1. ¡Crea un nuevo proyecto Maven! ssmbuild, agregar soporte web

2. ¡Importe dependencias pom relacionadas!

<dependencies>
   <!--Junit-->
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.12</version>
   </dependency>
   <!--数据库驱动-->
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>5.1.47</version>
   </dependency>
   <!-- 数据库连接池 -->
   <dependency>
       <groupId>com.mchange</groupId>
       <artifactId>c3p0</artifactId>
       <version>0.9.5.2</version>
   </dependency>
 
   <!--Servlet - JSP -->
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.5</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet.jsp</groupId>
       <artifactId>jsp-api</artifactId>
       <version>2.2</version>
   </dependency>
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>jstl</artifactId>
       <version>1.2</version>
   </dependency>
 
   <!--Mybatis-->
   <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis</artifactId>
       <version>3.5.2</version>
   </dependency>
   <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis-spring</artifactId>
       <version>2.0.2</version>
   </dependency>
 
   <!--Spring-->
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-webmvc</artifactId>
       <version>5.1.9.RELEASE</version>
   </dependency>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-jdbc</artifactId>
       <version>5.1.9.RELEASE</version>
   </dependency>
</dependencies>

3. Configuración de filtrado de recursos de Maven

<build>
   <resources>
       <resource>
           <directory>src/main/java</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
       <resource>
           <directory>src/main/resources</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>false</filtering>
       </resource>
   </resources>
</build>

4. ¡Establezca la estructura básica y el marco de configuración!

  • com.kuang.pojo
  • com.kuang.dao
  • com.kuang.servicio
  • com.kuang.controller
  • mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 
</configuration>
  • aplicaciónContext.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">
 
</beans>

4. Escritura de capas Mybatis

1. Archivo de configuración de la base de datos base de datos.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

2. Base de datos relacionada con IDEA

3. Escriba el archivo de configuración principal de MyBatis.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   
   <typeAliases>
       <package name="com.kuang.pojo"/>
   </typeAliases>
   <mappers>
       <mapper resource="com/kuang/dao/BookMapper.xml"/>
   </mappers>
 
</configuration>

4. Escriba la clase de entidad com.kuang.pojo.Books correspondiente a la base de datos.

¡Usa el complemento lombok!

package com.kuang.pojo;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
    
    
   
   private int bookID;
   private String bookName;
   private int bookCounts;
   private String detail;
   
}

5. ¡Escriba la interfaz Mapper de la capa Dao!

package com.kuang.dao;
 
import com.kuang.pojo.Books;
import java.util.List;
 
public interface BookMapper {
    
    
 
   //增加一个Book
   int addBook(Books book);
 
   //根据id删除一个Book
   int deleteBookById(int id);
 
   //更新Book
   int updateBook(Books books);
 
   //根据id查询,返回一个Book
   Books queryBookById(int id);
 
   //查询全部Book,返回list集合
   List<Books> queryAllBook();
 
}

6. Escriba el archivo Mapper.xml correspondiente a la interfaz. Necesita importar el paquete MyBatis;

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.kuang.dao.BookMapper">
 
   <!--增加一个Book-->
   <insert id="addBook" parameterType="Books">
      insert into ssmbuild.books(bookName,bookCounts,detail)
      values (#{bookName}, #{bookCounts}, #{detail})
   </insert>
 
   <!--根据id删除一个Book-->
   <delete id="deleteBookById" parameterType="int">
      delete from ssmbuild.books where bookID=#{bookID}
   </delete>
 
   <!--更新Book-->
   <update id="updateBook" parameterType="Books">
      update ssmbuild.books
      set bookName = #{bookName},bookCounts = #{bookCounts},detail = #{detail}
      where bookID = #{bookID}
   </update>
 
   <!--根据id查询,返回一个Book-->
   <select id="queryBookById" resultType="Books">
      select * from ssmbuild.books
      where bookID = #{bookID}
   </select>
 
   <!--查询全部Book-->
   <select id="queryAllBook" resultType="Books">
      SELECT * from ssmbuild.books
   </select>
 
</mapper>

7. Escriba la interfaz y la clase de implementación de la capa de Servicio.

interfaz:

package com.kuang.service;
 
import com.kuang.pojo.Books;
import java.util.List;
 
//BookService:底下需要去实现,调用dao层
public interface BookService {
    
    
   //增加一个Book
   int addBook(Books book);
   //根据id删除一个Book
   int deleteBookById(int id);
   //更新Book
   int updateBook(Books books);
   //根据id查询,返回一个Book
   Books queryBookById(int id);
   //查询全部Book,返回list集合
   List<Books> queryAllBook();
}

Clase de implementación:

package com.kuang.service;
 
import com.kuang.dao.BookMapper;
import com.kuang.pojo.Books;
import java.util.List;
 
public class BookServiceImpl implements BookService {
    
    
 
   //调用dao层的操作,设置一个set接口,方便Spring管理
   private BookMapper bookMapper;
 
   public void setBookMapper(BookMapper bookMapper) {
    
    
       this.bookMapper = bookMapper;
  }
   
   public int addBook(Books book) {
    
    
       return bookMapper.addBook(book);
  }
   
   public int deleteBookById(int id) {
    
    
       return bookMapper.deleteBookById(id);
  }
   
   public int updateBook(Books books) {
    
    
       return bookMapper.updateBook(books);
  }
   
   public Books queryBookById(int id) {
    
    
       return bookMapper.queryBookById(id);
  }
   
   public List<Books> queryAllBook() {
    
    
       return bookMapper.queryAllBook();
  }
}

Bien, en este punto, ¡la operación de requisitos subyacentes está completa!

5. capa de primavera

1. Configure Spring para integrar MyBatis. Nuestra fuente de datos aquí utiliza el grupo de conexiones c3p0;

2. Escribamos los archivos de configuración relevantes para la integración de Spring con Mybatis: spring-dao.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"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">
 
   <!-- 配置整合mybatis -->
   <!-- 1.关联数据库文件 -->
   <context:property-placeholder location="classpath:database.properties"/>
 
   <!-- 2.数据库连接池 -->
   <!--数据库连接池
       dbcp 半自动化操作 不能自动连接
       c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)
   -->
   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <!-- 配置连接池属性 -->
       <property name="driverClass" value="${jdbc.driver}"/>
       <property name="jdbcUrl" value="${jdbc.url}"/>
       <property name="user" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
 
       <!-- c3p0连接池的私有属性 -->
       <property name="maxPoolSize" value="30"/>
       <property name="minPoolSize" value="10"/>
       <!-- 关闭连接后不自动commit -->
       <property name="autoCommitOnClose" value="false"/>
       <!-- 获取连接超时时间 -->
       <property name="checkoutTimeout" value="10000"/>
       <!-- 当获取连接失败重试次数 -->
       <property name="acquireRetryAttempts" value="2"/>
   </bean>
 
   <!-- 3.配置SqlSessionFactory对象 -->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- 注入数据库连接池 -->
       <property name="dataSource" ref="dataSource"/>
       <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
       <property name="configLocation" value="classpath:mybatis-config.xml"/>
   </bean>
 
   <!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
   <!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 注入sqlSessionFactory -->
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
       <!-- 给出需要扫描Dao接口包 -->
       <property name="basePackage" value="com.kuang.dao"/>
   </bean>
 
</beans>

3. Spring integra la capa de servicio

<?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"
      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">
 
   <!-- 扫描service相关的bean -->
   <context:component-scan base-package="com.kuang.service" />
 
   <!--BookServiceImpl注入到IOC容器中-->
   <bean id="BookServiceImpl" class="com.kuang.service.BookServiceImpl">
       <property name="bookMapper" ref="bookMapper"/>
   </bean>
 
   <!-- 配置事务管理器 -->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!-- 注入数据库连接池 -->
       <property name="dataSource" ref="dataSource" />
   </bean>
 
</beans>

6. Capa SpringMVC

1.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
 
   <!--DispatcherServlet-->
   <servlet>
       <servlet-name>DispatcherServlet</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <!--一定要注意:我们这里加载的是总的配置文件,之前被这里坑了!-->  
           <param-value>classpath:applicationContext.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>DispatcherServlet</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
 
   <!--encodingFilter-->
   <filter>
       <filter-name>encodingFilter</filter-name>
       <filter-class>
          org.springframework.web.filter.CharacterEncodingFilter
       </filter-class>
       <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
       </init-param>
   </filter>
   <filter-mapping>
       <filter-name>encodingFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>
   
   <!--Session过期时间-->
   <session-config>
       <session-timeout>15</session-timeout>
   </session-config>
   
</web-app>

2、primavera-mvc.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"
      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
   https://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
   <!-- 配置SpringMVC -->
   <!-- 1.开启SpringMVC注解驱动 -->
   <mvc:annotation-driven />
   <!-- 2.静态资源默认servlet配置-->
   <mvc:default-servlet-handler/>
 
   <!-- 3.配置jsp 显示ViewResolver视图解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
       <property name="prefix" value="/WEB-INF/jsp/" />
       <property name="suffix" value=".jsp" />
   </bean>
 
   <!-- 4.扫描web相关的bean -->
   <context:component-scan base-package="com.kuang.controller" />
 
</beans>

3. Archivo de integración de configuración de Spring, applicationContext.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">
 
   <import resource="spring-dao.xml"/>
   <import resource="spring-service.xml"/>
   <import resource="spring-mvc.xml"/>
   
</beans>

¡Archivo de configuración, finalizado temporalmente! Escritura de capa de vista y controlador

1. Escribir la clase BookController, Método 1: consultar todos los libros

@Controller
@RequestMapping("/book")
public class BookController {
    
    
 
   @Autowired
   @Qualifier("BookServiceImpl")
   private BookService bookService;
 
   @RequestMapping("/allBook")
   public String list(Model model) {
    
    
       List<Books> list = bookService.queryAllBook();
       model.addAttribute("list", list);
       return "allBook";
  }
}

2. Escriba la página de inicio index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML>
<html>
<head>
   <title>首页</title>
   <style type="text/css">
       a {
      
      
           text-decoration: none;
           color: black;
           font-size: 18px;
      }
       h3 {
      
      
           width: 180px;
           height: 38px;
           margin: 100px auto;
           text-align: center;
           line-height: 38px;
           background: deepskyblue;
           border-radius: 4px;
      }
   </style>
</head>
<body>
 
<h3>
   <a href="${pageContext.request.contextPath}/book/allBook">点击进入列表页</a>
</h3>
</body>
</html>

3. Página de lista de libros allbook.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>书籍列表</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <!-- 引入 Bootstrap -->
   <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
 
<div class="container">
 
   <div class="row clearfix">
       <div class="col-md-12 column">
           <div class="page-header">
               <h1>
                   <small>书籍列表 —— 显示所有书籍</small>
               </h1>
           </div>
       </div>
   </div>
 
   <div class="row">
       <div class="col-md-4 column">
           <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增</a>
       </div>
   </div>
 
   <div class="row clearfix">
       <div class="col-md-12 column">
           <table class="table table-hover table-striped">
               <thead>
               <tr>
                   <th>书籍编号</th>
                   <th>书籍名字</th>
                   <th>书籍数量</th>
                   <th>书籍详情</th>
                   <th>操作</th>
               </tr>
               </thead>
 
               <tbody>
               <c:forEach var="book" items="${requestScope.get('list')}">
                   <tr>
                       <td>${book.getBookID()}</td>
                       <td>${book.getBookName()}</td>
                       <td>${book.getBookCounts()}</td>
                       <td>${book.getDetail()}</td>
                       <td>
                           <a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.getBookID()}">更改</a> |
                           <a href="${pageContext.request.contextPath}/book/del/${book.getBookID()}">删除</a>
                       </td>
                   </tr>
               </c:forEach>
               </tbody>
           </table>
       </div>
   </div>
</div>

4. Escribir la clase BookController, método dos: agregar libros

@RequestMapping("/toAddBook")
public String toAddPaper() {
    
    
   return "addBook";
}
 
@RequestMapping("/addBook")
public String addPaper(Books books) {
    
    
   System.out.println(books);
   bookService.addBook(books);
   return "redirect:/book/allBook";
}

5. Agregar página de libro: addBook.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 
<html>
<head>
   <title>新增书籍</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <!-- 引入 Bootstrap -->
   <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
 
   <div class="row clearfix">
       <div class="col-md-12 column">
           <div class="page-header">
               <h1>
                   <small>新增书籍</small>
               </h1>
           </div>
       </div>
   </div>
   <form action="${pageContext.request.contextPath}/book/addBook" method="post">
      书籍名称:<input type="text" name="bookName"><br><br><br>
      书籍数量:<input type="text" name="bookCounts"><br><br><br>
      书籍详情:<input type="text" name="detail"><br><br><br>
       <input type="submit" value="添加">
   </form>
 
</div>

6. Escribir la clase BookController, método tres: modificar libros

@RequestMapping("/toUpdateBook")
public String toUpdateBook(Model model, int id) {
    
    
   Books books = bookService.queryBookById(id);
   System.out.println(books);
   model.addAttribute("book",books );
   return "updateBook";
}
 
@RequestMapping("/updateBook")
public String updateBook(Model model, Books book) {
    
    
   System.out.println(book);
   bookService.updateBook(book);
   Books books = bookService.queryBookById(book.getBookID());
   model.addAttribute("books", books);
   return "redirect:/book/allBook";
}

7. Modifique la página del libro updateBook.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>修改信息</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <!-- 引入 Bootstrap -->
   <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
 
   <div class="row clearfix">
       <div class="col-md-12 column">
           <div class="page-header">
               <h1>
                   <small>修改信息</small>
               </h1>
           </div>
       </div>
   </div>
 
   <form action="${pageContext.request.contextPath}/book/updateBook" method="post">
       <input type="hidden" name="bookID" value="${book.getBookID()}"/>
      书籍名称:<input type="text" name="bookName" value="${book.getBookName()}"/>
      书籍数量:<input type="text" name="bookCounts" value="${book.getBookCounts()}"/>
      书籍详情:<input type="text" name="detail" value="${book.getDetail() }"/>
       <input type="submit" value="提交"/>
   </form>
 
</div>

8. Escribir la clase BookController, método cuatro: eliminar libros

@RequestMapping("/del/{bookId}")
public String deleteBook(@PathVariable("bookId") int id) {
    
    
   bookService.deleteBookById(id);
   return "redirect:/book/allBook";
}

¡Configure Tomcat y ejecútelo!

Hasta ahora, la integración del proyecto SSM está completamente bien y se puede ejecutar directamente para realizar pruebas. Este ejercicio es muy importante, ¡debes asegurarte de poder completarlo tú mismo sin mirar nada!

7. Cuadro de estructura del proyecto

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

8. Resumen y perspectivas

Este es el primer caso de integración SSM para estudiantes, ¡así que debes estar familiarizado con él!

La importancia del marco SSM es evidente: después de aprender esto, ya podrá desarrollar sitios web básicos de forma independiente. Pero esta es solo la operación básica de agregar, eliminar, modificar y verificar. Se puede decir que después de aprender esto, todos realmente han entrado por la puerta del desarrollo backend. Ése es el resultado final para encontrar un trabajo relacionado con la experiencia.

Quizás muchas personas simplemente hacen estas cosas por trabajo, pero no es suficiente para la mejora personal.

¡También aprenderemos algunos conocimientos sobre SpringMVC más adelante!

  • Ajax y Json
  • Carga y descarga de archivos
  • Interceptador

6. Oficina de interacción Json

1. ¿Qué es JSON?

  • JSON (JavaScript Object Notation, JS Object Markup) es un formato de intercambio de datos ligero que se utiliza ampliamente en la actualidad.
  • Almacene y represente datos en un formato de texto completamente independiente de los lenguajes de programación.
  • La simplicidad y la estructura jerárquica clara hacen de JSON un lenguaje de intercambio de datos ideal.
  • Es fácil de leer y escribir para las personas, y también es fácil de analizar y generar para las máquinas, y mejora efectivamente la eficiencia de transmisión de la red.

En el lenguaje JavaScript, todo es un objeto. Por tanto, cualquier tipo soportado por JavaScript puede representarse mediante JSON, como cadenas, números, objetos, matrices, etc. Eche un vistazo a sus requisitos y formato de sintaxis:

  • Los objetos se representan como pares clave-valor, con datos separados por comas.
  • Las llaves sostienen objetos
  • Los corchetes contienen matrices

Los pares clave-valor JSON son una forma de guardar objetos JavaScript. Están escritos de forma muy similar a los objetos JavaScript. Los nombres de las claves en la combinación de pares clave/valor se escriben delante y entre comillas dobles "", separadas por dos puntos. :, y luego siguió el valor:

{
    
    "name": "QinJiang"}
{
    
    "age": "3"}
{
    
    "sex": "男"}

Mucha gente no comprende la relación entre los objetos JSON y JavaScript, ni siquiera quién es quién. De hecho, se puede entender así:

JSON es la representación de cadena de objetos JavaScript y utiliza texto para representar la información de un objeto JS, que es esencialmente una cadena.

var obj = {
    
    a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串

2. Convierta objetos JSON y JavaScript entre sí

Para convertir una cadena JSON en un objeto JavaScript, utilice el método JSON.parse()

var obj = JSON.parse('{
    
    "a": "Hello", "b": "World"}');
//结果是 {a: 'Hello', b: 'World'}

Para convertir un objeto JavaScript en una cadena JSON, utilice el método JSON.stringify():

var json = JSON.stringify({
    
    a: 'Hello', b: 'World'});
//结果是 '{"a": "Hello", "b": "World"}'

prueba de código

1. Cree un nuevo módulo, springmvc-05-json, y agregue soporte web

2. Cree un nuevo json-1.html en el directorio web y escriba contenido de prueba.

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>JSON_秦疆</title>
</head>
<body>
 
<script type="text/javascript">
   //编写一个js的对象
   var user = {
      
      
       name:"秦疆",
       age:3,
       sex:"男"
  };
   //将js对象转换成json字符串
   var str = JSON.stringify(user);
   console.log(str);
   
   //将json字符串转换为js对象
   var user2 = JSON.parse(str);
   console.log(user2.age,user2.name,user2.sex);
 
</script>
 
</body>
</html>

3. ¡Ábralo con un navegador en IDEA y vea el resultado de la consola!

3. El controlador devuelve datos JSON

  • Jackson debería ser una mejor herramienta de análisis json en la actualidad.
  • Por supuesto, existen más que estas herramientas, como fastjson de Alibaba, etc.
  • Usamos Jackson aquí, y para usarlo necesitas importar su paquete jar;
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.9.8</version>
</dependency>
  • Configuración requerida para configurar SpringMVC

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
 
   <!--1.注册servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- 启动顺序,数字越小,启动越早 -->
       <load-on-startup>1</load-on-startup>
   </servlet>
 
   <!--所有请求都会被springmvc拦截 -->
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
 
   <filter>
       <filter-name>encoding</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
       </init-param>
   </filter>
   <filter-mapping>
       <filter-name>encoding</filter-name>
       <url-pattern>/</url-pattern>
   </filter-mapping>
 
</web-app>

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"
      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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
   <!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
   <context:component-scan base-package="com.kuang.controller"/>
 
   <!-- 视图解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
         id="internalResourceViewResolver">
       <!-- 前缀 -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- 后缀 -->
       <property name="suffix" value=".jsp" />
   </bean>
 
</beans>

Simplemente escribimos una clase de entidad Usuario y luego escribimos nuestro Controlador de prueba;

package com.kuang.pojo;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
//需要导入lombok
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
 
   private String name;
   private int age;
   private String sex;
   
}

Aquí necesitamos dos cosas nuevas, una es @ResponseBody y la otra es el objeto ObjectMapper. Echemos un vistazo al uso específico.

Escribe un controlador;

@Controller
public class UserController {
    
    
 
   @RequestMapping("/json1")
   @ResponseBody
   public String json1() throws JsonProcessingException {
    
    
       //创建一个jackson的对象映射器,用来解析数据
       ObjectMapper mapper = new ObjectMapper();
       //创建一个对象
       User user = new User("秦疆1号", 3, "男");
       //将我们的对象解析成为json格式
       String str = mapper.writeValueAsString(user);
       //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
       return str;
  }
 
}

Se descubre que hay un problema de código confuso, debemos configurar su formato de codificación en utf-8 y el tipo que devuelve;

Implementado a través del atributo produce de @RequestMaping, modifica el código

//produces:指定响应体返回类型和编码
@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")

Probado nuevamente, http://localhost:8080/json1¡el problema del código confuso está bien!

Insertar descripción de la imagen aquí
[Nota: recuerde tratar con caracteres confusos cuando use json]

Optimización de código

4. Solución unificada para códigos confusos

El método anterior es más problemático. Si hay muchas solicitudes en el proyecto, se deben agregar cada una. Puede especificarlas de manera uniforme a través de la configuración de Spring, para que no tenga que lidiar con ellas cada vez.

¡Podemos agregar una configuración de conversión de mensaje StringHttpMessageConverter al archivo de configuración springmvc!

<mvc:annotation-driven>
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.StringHttpMessageConverter">
           <construc	tor-arg value="UTF-8"/>
       </bean>
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                   <property name="failOnEmptyBeans" value="false"/>
               </bean>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

Devuelve una cadena json para una solución unificada

@RestController (simplemente agréguelo directamente a la clase)

Utilice @RestController directamente en la clase . De esta manera, todos los métodos en ella solo devolverán cadenas json. ¡No es necesario agregar @ResponseBody a cada uno! En nuestro desarrollo front-end y back-end por separado, generalmente usamos @RestController, ¡lo cual es muy conveniente!

@RestController
public class UserController {
    
    
 
   //produces:指定响应体返回类型和编码
   @RequestMapping(value = "/json1")
   public String json1() throws JsonProcessingException {
    
    
       //创建一个jackson的对象映射器,用来解析数据
       ObjectMapper mapper = new ObjectMapper();
       //创建一个对象
       User user = new User("秦疆1号", 3, "男");
       //将我们的对象解析成为json格式
       String str = mapper.writeValueAsString(user);
       //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
       return str;
  }
 
}

Solución @ResponseBody (se deben agregar todos los métodos, no se recomienda)

@Controller
public class UserController {
    
    
   //produces:指定响应体返回类型和编码
   @RequestMapping(value = "/json1")
   @ResponseBody
   public String json1() throws JsonProcessingException {
    
    
       //创建一个jackson的对象映射器,用来解析数据
       ObjectMapper mapper = new ObjectMapper();
       //创建一个对象
       User user = new User(1, "秦疆一号", 12);
       //将我们的对象解析成为json格式
       String str = mapper.writeValueAsString(user);
       //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
       return str;
  }
}

¡Inicie la prueba de Tomcat y los resultados se generarán normalmente!

5. Salida del equipo de prueba

Agregar un nuevo método

@RequestMapping("/json2")
public String json2() throws JsonProcessingException {
    
    
 
   //创建一个jackson的对象映射器,用来解析数据
   ObjectMapper mapper = new ObjectMapper();
   //创建一个对象
   User user1 = new User("秦疆1号", 3, "男");
   User user2 = new User("秦疆2号", 3, "男");
   User user3 = new User("秦疆3号", 3, "男");
   User user4 = new User("秦疆4号", 3, "男");
   List<User> list = new ArrayList<User>();
   list.add(user1);
   list.add(user2);
   list.add(user3);
   list.add(user4);
 
   //将我们的对象解析成为json格式
   String str = mapper.writeValueAsString(list);
   return str;
}

Resultados de carrera: ¡Perfecto, sin problemas!

Insertar descripción de la imagen aquí

6. Objeto de tiempo de salida

Agregar un nuevo método

@RequestMapping("/json3")
public String json3() throws JsonProcessingException {
    
    
 
   ObjectMapper mapper = new ObjectMapper();
 
   //创建时间一个对象,java.util.Date
   Date date = new Date();
   //将我们的对象解析成为json格式
   String str = mapper.writeValueAsString(date);
   return str;
}

resultado de la operación:

Insertar descripción de la imagen aquí

  • El formato de fecha predeterminado se convertirá en un número, que es el número de milisegundos desde el 1 de enero de 1970 hasta la fecha actual.
  • Jackson convertirá la hora en marcas de tiempo de forma predeterminada.

Solución: cancelar el formato de las marcas de tiempo y personalizar el formato de hora

@RequestMapping("/json4")
public String json4() throws JsonProcessingException {
    
    
 
   ObjectMapper mapper = new ObjectMapper();
 
   //不使用时间戳的方式
   mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
   //自定义日期格式对象
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   //指定日期格式
   mapper.setDateFormat(sdf);
 
   Date date = new Date();
   String str = mapper.writeValueAsString(date);
 
   return str;
}

Resultado de la operación: ¡La hora se emitió correctamente!

Insertar descripción de la imagen aquí

7. Extraer a la clase de herramienta

Si desea usarlo con frecuencia, esto es más problemático. Podemos encapsular estos códigos en una clase de herramienta, escribamos lo siguiente

package com.kuang.utils;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
 
import java.text.SimpleDateFormat;
 
public class JsonUtils {
    
    
   
   public static String getJson(Object object) {
    
    
       return getJson(object,"yyyy-MM-dd HH:mm:ss");
  }
 
   public static String getJson(Object object,String dateFormat) {
    
    
       ObjectMapper mapper = new ObjectMapper();
       //不使用时间差的方式
       mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
       //自定义日期格式对象
       SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
       //指定日期格式
       mapper.setDateFormat(sdf);
       try {
    
    
           return mapper.writeValueAsString(object);
      } catch (JsonProcessingException e) {
    
    
           e.printStackTrace();
      }
       return null;
  }
}

Cuando usamos clases de herramientas, ¡el código se vuelve más conciso!

@RequestMapping("/json5")
public String json5() throws JsonProcessingException {
    
    
   Date date = new Date();
   String json = JsonUtils.getJson(date);
   return json;
}

¡Ya terminaste! ¡Perfecto!

8. FastJson

fastjson.jar es un paquete desarrollado por Alibaba específicamente para el desarrollo de Java, que puede convertir fácilmente objetos json y objetos JavaBean, convertir objetos JavaBean y cadenas json, y convertir objetos json y cadenas json. Hay muchas formas de convertir json y el resultado final es el mismo.

dependencia fastjson pom!

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.60</version>
</dependency>

fastjson tiene tres clases principales:

JSONObject representa el objeto json

  • JSONObject implementa la interfaz Map y se supone que las operaciones subyacentes de JSONObject las implementa Map.
  • JSONObject corresponde al objeto json. Puede obtener los datos en el objeto json a través de varias formas de métodos get(). También puede usar métodos como size() e isEmpty() para obtener el número de pares "clave: valor". y determinar si están vacíos. Su esencia es implementar la interfaz Map y llamar a los métodos en la interfaz.

JSONArray representa una matriz de objetos json

  • Internamente, existen métodos en la interfaz Lista para completar la operación.

JSON representa la conversión de JSONObject y JSONArray

  • Análisis y uso del código fuente de la clase JSON
  • Observe estos métodos con atención, principalmente implementan la conversión mutua entre objetos json, matrices de objetos json, objetos javabean y cadenas json.

Para probar el código, creamos una nueva clase FastJsonDemo.

package com.kuang.controller;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kuang.pojo.User;
 
import java.util.ArrayList;
import java.util.List;
 
public class FastJsonDemo {
    
    
   public static void main(String[] args) {
    
    
       //创建一个对象
       User user1 = new User("秦疆1号", 3, "男");
       User user2 = new User("秦疆2号", 3, "男");
       User user3 = new User("秦疆3号", 3, "男");
       User user4 = new User("秦疆4号", 3, "男");
       List<User> list = new ArrayList<User>();
       list.add(user1);
       list.add(user2);
       list.add(user3);
       list.add(user4);
 
       System.out.println("*******Java对象 转 JSON字符串*******");
       String str1 = JSON.toJSONString(list);
       System.out.println("JSON.toJSONString(list)==>"+str1);
       String str2 = JSON.toJSONString(user1);
       System.out.println("JSON.toJSONString(user1)==>"+str2);
 
       System.out.println("\n****** JSON字符串 转 Java对象*******");
       User jp_user1=JSON.parseObject(str2,User.class);
       System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
 
       System.out.println("\n****** Java对象 转 JSON对象 ******");
       JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
       System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
 
       System.out.println("\n****** JSON对象 转 Java对象 ******");
       User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
       System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
  }
}

Solo necesitamos dominar el uso de este tipo de herramientas y, al utilizarlas, debemos encontrar la implementación correspondiente según el negocio específico. Al igual que el conjunto de herramientas commons-io anterior, ¡simplemente úselo!

7. Investigación Ajax

1. Introducción

  • AJAX = JavaScript y XML asincrónicos.
  • AJAX es una tecnología que le permite actualizar partes de una página web sin recargar toda la página.
  • Ajax no es un nuevo lenguaje de programación, sino una tecnología para crear aplicaciones web mejores, más rápidas y más interactivas.
  • En 2005, Google hizo popular AJAX con su Google Suggest. Google Suggest puede completar automáticamente los términos de búsqueda por usted.
  • Google Suggest utiliza AJAX para crear una interfaz web altamente dinámica: cuando ingresa palabras clave en el cuadro de búsqueda de Google, JavaScript envía estos caracteres al servidor y el servidor devuelve una lista de sugerencias de búsqueda.
  • ¡Al igual que el cuadro de búsqueda nacional de Baidu!
  • Para las páginas web tradicionales (es decir, páginas web sin tecnología Ajax), si desea actualizar el contenido o enviar un formulario, debe recargar toda la página web.
  • Las páginas web que utilizan tecnología Ajax pueden lograr actualizaciones parciales asincrónicas intercambiando una pequeña cantidad de datos en el servidor en segundo plano.
  • Con Ajax, los usuarios pueden crear interfaces de usuario web directas, de alta disponibilidad, más ricas y más dinámicas, cercanas a las aplicaciones de escritorio nativas.

2. Ajax falso

Podemos usar una etiqueta en la parte frontal para simular una apariencia ajax. etiqueta de marco flotante

1. Cree un nuevo módulo: sspringmvc-06-ajax, importe soporte web
2. Escriba un ajax-frame.html y use iframe para probar y sentir el efecto

<!DOCTYPE html>
<html>
<head lang="en">
   <meta charset="UTF-8">
   <title>kuangshen</title>
</head>
<body>
 
<script type="text/javascript">
   window.onload = function(){
    
    
       var myDate = new Date();
       document.getElementById('currentTime').innerText = myDate.getTime();
  };
 
   function LoadPage(){
    
    
       var targetUrl =  document.getElementById('url').value;
       console.log(targetUrl);
       document.getElementById("iframePosition").src = targetUrl;
  }
 
</script>
 
<div>
   <p>请输入要加载的地址:<span id="currentTime"></span></p>
   <p>
       <input id="url" type="text" value="https://www.baidu.com/"/>
       <input type="button" value="提交" onclick="LoadPage()">
   </p>
</div>
 
<div>
   <h3>加载页面位置:</h3>
   <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div>
 
</body>
</html>

3. ¡Utilice IDEA para abrir un navegador y probarlo!

Puedes usar AJAX para hacer:

  • Al registrarse, ingrese el nombre de usuario para detectar automáticamente si el usuario ya existe.
  • Al iniciar sesión, me indica que el nombre de usuario y la contraseña son incorrectos.
  • Al eliminar una fila de datos, la ID de la fila se envía al fondo y el fondo la elimina en la base de datos. Una vez que la base de datos se elimina correctamente, la fila de datos también se elimina en la página DOM.
  • …etc

3. jQuery.ajax

Aquí no explicaremos la implementación nativa JS pura de Ajax, usaremos directamente la proporcionada por jquery, que es conveniente para el aprendizaje y el uso y evita reinventar la rueda. ¡Los estudiantes interesados ​​​​pueden aprender sobre XMLHttpRequest nativo de JS!

El núcleo de Ajax es el objeto XMLHttpRequest (XHR). XHR proporciona una interfaz para enviar solicitudes al servidor y analizar las respuestas del servidor. Capacidad de obtener nuevos datos del servidor de forma asincrónica.

jQuery proporciona varios métodos relacionados con AJAX.

Con los métodos jQuery AJAX, puede solicitar texto, HTML, XML o JSON desde un servidor remoto utilizando HTTP Get y HTTP Post, y puede cargar estos datos externos directamente en elementos seleccionados de la página web.

jQuery no es un productor, es un portero de la naturaleza.

La esencia de jQuery Ajax es XMLHttpRequest, que está encapsulado para facilitar las llamadas.

jQuery.ajax(...)
      部分参数:
            url:请求地址
            type:请求方式,GETPOST1.9.0之后用method)
        headers:请求头
            data:要发送的数据
    contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
          async:是否异步
        timeout:设置请求超时时间(毫秒)
      beforeSend:发送请求前执行的函数(全局)
        complete:完成之后执行的回调函数(全局)
        success:成功之后执行的回调函数(全局)
          error:失败之后执行的回调函数(全局)
        accepts:通过请求头发送给服务器,告诉服务器当前客户端可接受的数据类型
        dataType:将服务器端返回的数据转换成指定类型
          "xml": 将服务器端返回的内容转换成xml格式
          "text": 将服务器端返回的内容转换成普通文本格式
          "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
        "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
          "json": 将服务器端返回的内容转换成相应的JavaScript对象
        "jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数

Hagamos una prueba sencilla, utilizando el procesamiento HttpServletResponse más original, el más simple y versátil.

1. Configure los archivos de configuración de web.xml y springmvc, simplemente copie el caso anterior [recuerde la configuración del controlador de anotaciones y filtrado de recursos estáticos]

<?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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
   <!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
   <context:component-scan base-package="com.kuang.controller"/>
   <mvc:default-servlet-handler />
   <mvc:annotation-driven />
 
   <!-- 视图解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
         id="internalResourceViewResolver">
       <!-- 前缀 -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- 后缀 -->
       <property name="suffix" value=".jsp" />
   </bean>
 
</beans>

2. Escribe un controlador Ajax

@Controller
public class AjaxController {
    
    
 
   @RequestMapping("/a1")
   public void ajax1(String name , HttpServletResponse response) throws IOException {
    
    
       if ("admin".equals(name)){
    
    
           response.getWriter().print("true");
      }else{
    
    
           response.getWriter().print("false");
      }
  }
 
}

3. Importe jquery. Puede utilizar un CDN en línea o descargarlo e importarlo.

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="${pageContext.request.contextPath}/statics/js/jquery-3.1.1.min.js"></script>

4. Escriba la prueba index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
  <%--<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>--%>
   <script src="${pageContext.request.contextPath}/statics/js/jquery-3.1.1.min.js"></script>
   <script>
       function a1(){
      
      
           $.post({
      
      
               url:"${pageContext.request.contextPath}/a1",
               data:{
      
      'name':$("#txtName").val()},
               success:function (data,status) {
      
      
                   alert(data);
                   alert(status);
              }
          });
      }
   </script>
 </head>
 <body>
 
<%--onblur:失去焦点触发事件--%>
用户名:<input type="text" id="txtName" onblur="a1()"/>
 
 </body>
</html>

5. ¡Inicie la prueba de Tomcat! Abra la consola del navegador. Cuando nuestro mouse sale del cuadro de entrada, podemos ver que se emite una solicitud ajax. ¡Es el resultado que nos devuelve el fondo! ¡Éxito de la prueba!

4. Implementación de Springmvc

Usuario de clase de entidad

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
 
   private String name;
   private int age;
   private String sex;
 
}

Obtengamos un objeto de colección y mostrémoslo en la página de inicio.

@RequestMapping("/a2")
public List<User> ajax2(){
    
    
   List<User> list = new ArrayList<User>();
   list.add(new User("秦疆1号",3,"男"));
   list.add(new User("秦疆2号",3,"男"));
   list.add(new User("秦疆3号",3,"男"));
   return list; //由于@RestController注解,将list转成json格式返回
}

Página de inicio

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<input type="button" id="btn" value="获取数据"/>
<table width="80%" align="center">
   <tr>
       <td>姓名</td>
       <td>年龄</td>
       <td>性别</td>
   </tr>
   <tbody id="content">
   </tbody>
</table>
 
<script src="${pageContext.request.contextPath}/statics/js/jquery-3.1.1.min.js"></script>
<script>
 
   $(function () {
      
      
       $("#btn").click(function () {
      
      
           $.post("${pageContext.request.contextPath}/a2",function (data) {
      
      
               console.log(data)
               var html="";
               for (var i = 0; i <data.length ; i++) {
      
      
                   html+= "<tr>" +
                       "<td>" + data[i].name + "</td>" +
                       "<td>" + data[i].age + "</td>" +
                       "<td>" + data[i].sex + "</td>" +
                       "</tr>"
              }
               $("#content").html(html);
          });
      })
  })
</script>
</body>
</html>

¡El eco de datos se implementó con éxito! ¡Puedes experimentar los beneficios de Ajax!

5. Efecto de aviso de registro

Probemos una pequeña demostración nuevamente y pensemos en cómo lograr el aviso en tiempo real detrás del cuadro de entrada cuando normalmente nos registramos; cómo optimizarlo.

Escribamos un controlador

@RequestMapping("/a3")
public String ajax3(String name,String pwd){
    
    
   String msg = "";
   //模拟数据库中存在数据
   if (name!=null){
    
    
       if ("admin".equals(name)){
    
    
           msg = "OK";
      }else {
    
    
           msg = "用户名输入错误";
      }
  }
   if (pwd!=null){
    
    
       if ("123456".equals(pwd)){
    
    
           msg = "OK";
      }else {
    
    
           msg = "密码输入有误";
      }
  }
   return msg; //由于@RestController注解,将msg转成json格式返回
}

Página de inicio login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>ajax</title>
   <script src="${pageContext.request.contextPath}/statics/js/jquery-3.1.1.min.js"></script>
   <script>
 
       function a1(){
      
      
           $.post({
      
      
               url:"${pageContext.request.contextPath}/a3",
               data:{
      
      'name':$("#name").val()},
               success:function (data) {
      
      
                   if (data.toString()=='OK'){
      
      
                       $("#userInfo").css("color","green");
                  }else {
      
      
                       $("#userInfo").css("color","red");
                  }
                   $("#userInfo").html(data);
              }
          });
      }
       function a2(){
      
      
           $.post({
      
      
               url:"${pageContext.request.contextPath}/a3",
               data:{
      
      'pwd':$("#pwd").val()},
               success:function (data) {
      
      
                   if (data.toString()=='OK'){
      
      
                       $("#pwdInfo").css("color","green");
                  }else {
      
      
                       $("#pwdInfo").css("color","red");
                  }
                   $("#pwdInfo").html(data);
              }
          });
      }
 
   </script>
</head>
<body>
<p>
  用户名:<input type="text" id="name" onblur="a1()"/>
   <span id="userInfo"></span>
</p>
<p>
  密码:<input type="text" id="pwd" onblur="a2()"/>
   <span id="pwdInfo"></span>
</p>
</body>
</html>

[Recuerde solucionar el problema de json confuso]

Pruebe el efecto, respuesta de solicitud dinámica, actualización parcial, ¡eso es todo!

6. Obtenga la demostración de la interfaz de Baidu

<!DOCTYPE HTML>
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <title>JSONP百度搜索</title>
   <style>
       #q{
      
      
           width: 500px;
           height: 30px;
           border:1px solid #ddd;
           line-height: 30px;
           display: block;
           margin: 0 auto;
           padding: 0 10px;
           font-size: 14px;
      }
       #ul{
      
      
           width: 520px;
           list-style: none;
           margin: 0 auto;
           padding: 0;
           border:1px solid #ddd;
           margin-top: -1px;
           display: none;
      }
       #ul li{
      
      
           line-height: 30px;
           padding: 0 10px;
      }
       #ul li:hover{
      
      
           background-color: #f60;
           color: #fff;
      }
   </style>
   <script>
 
       // 2.步骤二
       // 定义demo函数 (分析接口、数据)
       function demo(data){
      
      
           var Ul = document.getElementById('ul');
           var html = '';
           // 如果搜索数据存在 把内容添加进去
           if (data.s.length) {
      
      
               // 隐藏掉的ul显示出来
               Ul.style.display = 'block';
               // 搜索到的数据循环追加到li里
               for(var i = 0;i<data.s.length;i++){
      
      
                   html += '<li>'+data.s[i]+'</li>';
              }
               // 循环的li写入ul
               Ul.innerHTML = html;
          }
      }
 
       // 1.步骤一
       window.onload = function(){
      
      
           // 获取输入框和ul
           var Q = document.getElementById('q');
           var Ul = document.getElementById('ul');
 
           // 事件鼠标抬起时候
           Q.onkeyup = function(){
      
      
               // 如果输入框不等于空
               if (this.value != '') {
      
      
                   // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆JSONPz重点☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
                   // 创建标签
                   var script = document.createElement('script');
                   //给定要跨域的地址 赋值给src
                   //这里是要请求的跨域的地址 我写的是百度搜索的跨域地址
                   script.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+this.value+'&cb=demo';
                   // 将组合好的带src的script标签追加到body里
                   document.body.appendChild(script);
              }
          }
      }
   </script>
</head>
 
<body>
<input type="text" id="q" />
<ul id="ul">
 
</ul>
</body>
</html>

8. interceptor

1. Información general

El interceptor de procesador de SpringMVC es similar al filtro en el desarrollo de Servlet, que se utiliza para preprocesar y posprocesar el procesador. Los desarrolladores pueden definir algunos interceptores para implementar funciones específicas.

La diferencia entre filtros e interceptores : Los interceptores son una aplicación específica de las ideas de AOP .

filtrar

  • Parte de la especificación del servlet, cualquier proyecto web Java puede usarlo
  • Después de configurar /* en el patrón de URL, se pueden interceptar todos los recursos a los que se accede.

Interceptador

  • El interceptor es propio del marco SpringMVC y solo puede ser utilizado por proyectos que utilizan el marco SpringMVC.
  • El interceptor solo interceptará el método del controlador al que se accede. Si el acceso es jsp/html/css/image/js, no será interceptado.

2. Interceptor personalizado

Entonces, ¿cómo implementar un interceptor?

Si desea personalizar el interceptor, debe implementar la interfaz HandlerInterceptor.

1. Cree un nuevo módulo, springmvc-07-Interceptor y agregue soporte web

2. Configure los archivos web.xml y springmvc-servlet.xml

3. Escribe un interceptor

package com.kuang.interceptor;
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class MyInterceptor implements HandlerInterceptor {
    
    
 
   //在请求处理的方法之前执行
   //如果返回true执行下一个拦截器
   //如果返回false就不执行下一个拦截器
   public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    
    
       System.out.println("------------处理前------------");
       return true;
  }
 
   //在请求处理方法执行之后执行
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
    
       System.out.println("------------处理后------------");
  }
 
   //在dispatcherServlet处理后执行,做清理工作.
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    
    
       System.out.println("------------清理------------");
  }
}

4. Configure el interceptor en el archivo de configuración springmvc.

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <!--/** 包括路径及其子路径-->
       <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
       <!--/admin/** 拦截的是/admin/下的所有-->
       <mvc:mapping path="/**"/>
       <!--bean配置的就是拦截器-->
       <bean class="com.kuang.interceptor.MyInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

5. Escriba un controlador para recibir solicitudes.

package com.kuang.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
//测试拦截器的控制器
@Controller
public class InterceptorController {
    
    
 
   @RequestMapping("/interceptor")
   @ResponseBody
   public String testFunction() {
    
    
       System.out.println("控制器中的方法执行了");
       return "hello";
  }
}

6. Index.jsp de interfaz de usuario

<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a>

7. ¡Inicie Tomcat y pruébelo!

3. Verifique si el usuario ha iniciado sesión (usuario autenticado)

Ideas de implementación

  1. Hay una página de inicio de sesión y necesita escribir un controlador para acceder a la página.
  2. La página de inicio de sesión tiene una acción para enviar el formulario. Debe manejarse en el controlador. Determine si el nombre de usuario y la contraseña son correctos. Si es correcto, escriba la información del usuario en la sesión. Vuelva a iniciar sesión correctamente.
  3. Intercepte las solicitudes de los usuarios y determine si el usuario ha iniciado sesión. Si el usuario ya ha iniciado sesión. Suelte, si el usuario no ha iniciado sesión, salte a la página de inicio de sesión

prueba:

1. Escriba una página de inicio de sesión login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
 
<h1>登录页面</h1>
<hr>
 
<body>
<form action="${pageContext.request.contextPath}/user/login">
  用户名:<input type="text" name="username"> <br>
  密码:<input type="password" name="pwd"> <br>
   <input type="submit" value="提交">
</form>
</body>
</html>

2. Escriba un controlador para manejar la solicitud.

package com.kuang.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import javax.servlet.http.HttpSession;
 
@Controller
@RequestMapping("/user")
public class UserController {
    
    
 
   //跳转到登陆页面
   @RequestMapping("/jumplogin")
   public String jumpLogin() throws Exception {
    
    
       return "login";
  }
 
   //跳转到成功页面
   @RequestMapping("/jumpSuccess")
   public String jumpSuccess() throws Exception {
    
    
       return "success";
  }
 
   //登陆提交
   @RequestMapping("/login")
   public String login(HttpSession session, String username, String pwd) throws Exception {
    
    
       // 向session记录用户身份信息
       System.out.println("接收前端==="+username);
       session.setAttribute("user", username);
       return "success";
  }
 
   //退出登陆
   @RequestMapping("logout")
   public String logout(HttpSession session) throws Exception {
    
    
       // session 过期
       session.invalidate();
       return "login";
  }
}

3. Escriba una página de inicio de sesión exitosa Success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
 
<h1>登录成功页面</h1>
<hr>
 
${user}
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</body>
</html>

4. ¡Pruebe el salto en la página de índice! Inicie la prueba de Tomcat y podrá ingresar a la página de inicio incluso si no ha iniciado sesión.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
 </head>
 <body>
 <h1>首页</h1>
 <hr>
<%--登录--%>
 <a href="${pageContext.request.contextPath}/user/jumplogin">登录</a>
 <a href="${pageContext.request.contextPath}/user/jumpSuccess">成功页面</a>
 </body>
</html>

5. Escribir interceptor de inicio de sesión de usuario

package com.kuang.interceptor;
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
 
public class LoginInterceptor implements HandlerInterceptor {
    
    
 
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
    
    
       // 如果是登陆页面则放行
       System.out.println("uri: " + request.getRequestURI());
       if (request.getRequestURI().contains("login")) {
    
    
           return true;
      }
 
       HttpSession session = request.getSession();
 
       // 如果用户已登陆也放行
       if(session.getAttribute("user") != null) {
    
    
           return true;
      }
 
       // 用户没有登陆跳转到登陆页面
       request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
       return false;
  }
 
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
    
 
  }
   
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    
    
 
  }
}

6. Registre el interceptor en el archivo de configuración Springmvc.

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <mvc:mapping path="/**"/>
       <bean id="loginInterceptor" class="com.kuang.interceptor.LoginInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

7. ¡Reinicie la prueba de Tomcat nuevamente!

Bien, la función de interceptación de inicio de sesión de prueba es correcta.

9. Carga y descarga de archivos

1. Preparación

La carga de archivos es una de las funciones más comunes en el desarrollo de proyectos. SpringMVC puede admitir muy bien la carga de archivos, pero MultipartResolver no está instalado de forma predeterminada en el contexto SpringMVC, por lo que no puede manejar la carga de archivos de forma predeterminada. Si desea utilizar la función de carga de archivos de Spring, debe configurar MultipartResolver en el contexto.

Requisitos del formulario de front-end: para cargar archivos, el método del formulario debe configurarse en POST y el tipo de cifrado debe configurarse en multipart/form-data. Sólo en este caso el navegador enviará el archivo seleccionado por el usuario al servidor como datos binarios;

Dé una explicación detallada del atributo enctype en el formulario:

  • application/x-www=form-urlencoded: el método predeterminado solo procesa el valor del atributo de valor en el campo del formulario. Un formulario que utiliza este método de codificación procesará el valor en el campo del formulario en codificación URL.
  • multipart/form-data: este método de codificación procesará los datos del formulario en una secuencia binaria. Este método de codificación también encapsulará el contenido del archivo especificado en el campo del archivo en los parámetros de solicitud y no codificará caracteres.
  • texto/sin formato: excepto para convertir espacios en signos "+", otros caracteres no están codificados. Este método es adecuado para enviar correos electrónicos directamente a través del formulario.
<form action="" enctype="multipart/form-data" method="post">
   <input type="file" name="file"/>
   <input type="submit">
</form>

Una vez que el enctype se establece en multipart/form-data, el navegador utilizará una secuencia binaria para procesar los datos del formulario, mientras que el procesamiento de cargas de archivos implica analizar la respuesta HTTP original en el lado del servidor. En 2003, la Apache Software Foundation lanzó el componente de código abierto Commons FileUpload, que rápidamente se convirtió en la mejor opción para que los programadores de Servlet/JSP cargaran archivos.

  • La especificación Servlet3.0 ya proporciona métodos para manejar la carga de archivos, pero esta carga debe completarse en el Servlet.
  • Spring MVC proporciona una encapsulación más simple.
  • Spring MVC proporciona soporte directo para la carga de archivos, que se implementa mediante MultipartResolver plug-and-play.
  • Spring MVC utiliza la tecnología Apache Commons FileUpload para implementar una clase de implementación MultipartResolver:
  • CommonsMultipartResolver. Por lo tanto, la carga de archivos de SpringMVC también debe depender del componente Apache Commons FileUpload.

2. Carga de archivos

1. Importe el paquete jar para cargar archivos, commons-fileupload. Maven nos ayudará automáticamente a importar su paquete dependiente commons-io;

<!--文件上传-->
<dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>4.0.1</version>
</dependency>

2. Bean de colocación: multipartResolver

【¡Aviso! ! ! La identificación de este bena debe ser: multipartResolver; de lo contrario, se informará un error 400 al cargar archivos. ¡Caí en una trampa aquí y aprendí una lección!

<!--文件上传配置-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
   <property name="defaultEncoding" value="utf-8"/>
   <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
   <property name="maxUploadSize" value="10485760"/>
   <property name="maxInMemorySize" value="40960"/>
</bean>

Métodos comunes de CommonsMultipartFile:

  • String getOriginalFilename(): obtiene el nombre original del archivo cargado
  • InputStream getInputStream(): obtiene la secuencia del archivo
  • void transferTo(Destino del archivo): guarda el archivo cargado en un archivo de directorio

Vamos a probarlo.

3. Escribe la página de inicio.

<form action="/upload" enctype="multipart/form-data" method="post">
 <input type="file" name="file"/>
 <input type="submit" value="upload">
</form>

4. Controlador

package com.kuang.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
import javax.servlet.http.HttpServletRequest;
import java.io.*;
 
@Controller
public class FileController {
    
    
   //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
   //批量上传CommonsMultipartFile则为数组即可
   @RequestMapping("/upload")
   public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
    
    
 
       //获取文件名 : file.getOriginalFilename();
       String uploadFileName = file.getOriginalFilename();
 
       //如果文件名为空,直接回到首页!
       if ("".equals(uploadFileName)){
    
    
           return "redirect:/index.jsp";
      }
       System.out.println("上传文件名 : "+uploadFileName);
 
       //上传路径保存设置
       String path = request.getServletContext().getRealPath("/upload");
       //如果路径不存在,创建一个
       File realPath = new File(path);
       if (!realPath.exists()){
    
    
           realPath.mkdir();
      }
       System.out.println("上传文件保存地址:"+realPath);
 
       InputStream is = file.getInputStream(); //文件输入流
       OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
 
       //读取写出
       int len=0;
       byte[] buffer = new byte[1024];
       while ((len=is.read(buffer))!=-1){
    
    
           os.write(buffer,0,len);
           os.flush();
      }
       os.close();
       is.close();
       return "redirect:/index.jsp";
  }
}

2. Modificación de la dirección de envío del formulario front-end

3. Visite y envíe la prueba, ¡OK!

3. Descarga de archivos

Pasos para descargar el archivo:

  1. Establecer encabezado de respuesta
  2. Lectura de archivos – InputStream
  3. Escribir archivo – OutputStream
  4. realizar operaciones
  5. Cerrar la transmisión (primero abrir y luego cerrar)

Código:

@RequestMapping(value="/download")
public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{
    
    
   //要下载的图片地址
   String  path = request.getServletContext().getRealPath("/upload");
   String  fileName = "基础语法.jpg";
 
   //1、设置response 响应头
   response.reset(); //设置页面不缓存,清空buffer
   response.setCharacterEncoding("UTF-8"); //字符编码
   response.setContentType("multipart/form-data"); //二进制传输数据
   //设置响应头
   response.setHeader("Content-Disposition",
           "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
 
   File file = new File(path,fileName);
   //2、 读取文件--输入流
   InputStream input=new FileInputStream(file);
   //3、 写出文件--输出流
   OutputStream out = response.getOutputStream();
 
   byte[] buff =new byte[1024];
   int index=0;
   //4、执行 写出操作
   while((index= input.read(buff))!= -1){
    
    
       out.write(buff, 0, index);
       out.flush();
  }
   out.close();
   input.close();
   return null;
}

Interfaz

<a href="/download">点击下载</a>

Pruebe, la descarga del archivo está bien, puede compararlo con el método nativo JavaWeb que aprendimos antes y sabrá que esto es mucho más conveniente.

Supongo que te gusta

Origin blog.csdn.net/weixin_45888036/article/details/131182377
Recomendado
Clasificación