Desarrollo del programa SpringMVC

1. ¿Qué es SpringMVC?

Descripción oficial: https://docs.spring.io/springframework/docs/current/reference/html/web.html#spring-web

Traducido al chino: Spring Web MVC se basa en Servlet API 构建的原始 Web 框架, desde el principio 包含在 Spring 框架中. Su nombre oficial "Spring Web MVC" proviene del nombre de su módulo fuente (Spring-webmvc), pero a menudo se le conoce como "SpringMVC".

1.1 ¿Qué es MVC?

Model View Controller(模型,视图,控制器), es un 设计模式patrón de diseño que divide el software (proyecto) en tres partes:模型,视图,控制器
inserte la descripción de la imagen aquí

Modelo (modelo) es la parte de la aplicación que se utiliza para procesar la lógica de datos de la aplicación. Por lo general, el objeto modelo es responsable de acceder a los datos en la base de datos.

Vista (vista) es la parte de la aplicación que maneja la visualización de datos.Por lo general, las vistas se crean a partir de datos del modelo.

El controlador es la parte de la aplicación que maneja la interacción del usuario. Por lo general, el controlador es responsable de leer los datos de la vista, controlar la entrada del usuario y enviar datos al modelo...

1.2 ¿Cuál es la relación entre MVC y SpringMVC?

MVC es un tipo 设计思想y SpringMVC es un 具体的实现marco .

SpringMVC es un marco web basado en el patrón de diseño MVC y la implementación de la API Servlet. Al mismo tiempo, SpringMVC es un módulo WEB en el marco Spring. Es un marco que existe con el nacimiento de Spring.
Spring y SpringMVC tienen una larga historia . de nacimiento Después de eso, hay arranque de primavera.

2. Creación del proyecto Spring MVC

Siempre que agreguemos una dependencia Spring Web (que usa Spring MVC) basada en el marco Spring Boot, el proyecto en este momento se convierte en un proyecto Spring MVC.
inserte la descripción de la imagen aquí

Aprendemos SpringMVC principalmente para aprender:

  1. Implemente el mapeo entre usuarios y programas (después de que el navegador ingrese la dirección URL, el método correspondiente puede coincidir en el programa)
  2. El servidor necesita obtener los parámetros de solicitud del usuario.
  3. El servidor devolverá el resultado al usuario.

2.1 Uso del mapeo de usuarios y programas

2.1.1 Método 1: Usar @RequestMapping(“/xxx”)

Cree una UserControllerclase para realizar la interconexión entre los usuarios y los programas de Spring:

inserte la descripción de la imagen aquí

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody // 表示的是返回一个非静态页面的数据
@RequestMapping("/user") //类上面的 RequestMapping 可以省略
public class UserController {
    
    

    @RequestMapping("/sayhi")
    public String sayHi(){
    
    
        return "Hello World!";
    }
}

Después del inicio: ingrese en el navegador:http://localhost:8080/user/sayhi
inserte la descripción de la imagen aquí

tip:
inserte la descripción de la imagen aquí

@RequestMapping 特征:

  1. Puede modificar tanto las clases (opcional) como los métodos.
  2. De forma predeterminada, se admiten los métodos de solicitud POST y GET

Puede usarlo para Postmanverificar :
Postmanmétodo de descarga: https://blog.csdn.net/chenbaifan/article/details/124850501?spm=1001.2014.3001.5501

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

@RequestMappingExpansión de parámetros (solo admite un cierto tipo de método de solicitud, como el método de solicitud de tipo POST):

@RequestMapping(method = RequestMethod.POST,value = "/sayhi")

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

Solo se admite GET:
inserte la descripción de la imagen aquí

@RequestMapping(method = RequestMethod.GET,value = "/sayhi")

2.1.2 Método 2: Usar @PostMapping(“/xxx”)

Solo admite el método de solicitud POST
@PostMapping("/sayhi2")
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2.1.3 Método 3: Usar @GetMapping(“/xxx”)

Solo admite el método de solicitud GET
@GetMapping("/sayhi3")
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Resumen: @RequestMappingtanto GET como POST son compatibles, pero también puede configurar el GET o POST especificado
@GetMappingpara que solo admita solicitudes GET y PostMappingPOST.

2.2 Obtener parámetros de solicitud de usuario

2.2.1 Obtener un único parámetro

Objeto:
inserte la descripción de la imagen aquí

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

2.2.2 Obtener múltiples parámetros

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

2.2.3 Obtener objetos

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

2.2.4 Cambio de nombre de parámetros (anotación (@RequesParam)

En algunos casos especiales, la clave de parámetro pasada por el front-end puede ser inconsistente con la clave recibida por nuestro back-end.Por ejemplo, el front-end pasa un nombre al back-end, mientras que el back-end tiene un campo de nombre de usuario para recibir, por lo que habrá una situación en la que no se pueden recibir los parámetros. Si esto sucede, podemos usar @RequestParam para cambiar el nombre de los valores de los parámetros de los extremos frontal y posterior.
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

Incorrecto:
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

Notas sobre el uso de la anotación @RequestParam:
si agrega la anotación @RequestParam al parámetro, entonces el front-end debe pasar este parámetro; de lo contrario, se informará un error. Si desea resolver este problema, puede agregarlo a @RequestParam required = false

Error informado:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Modificado:
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

2.2.5 Obtener datos en formato JSON (@RequestBody)

Para usar @RequestBodyesta anotación:
inserte la descripción de la imagen aquí

Luego use Postman para simular el envío de datos JSON al servidor:

inserte la descripción de la imagen aquí

2.2.6 Obtener parámetros de la dirección URL (@PathVariable)

注意:No estoy hablando de obtener parámetros de la parte de parámetros en la dirección URL
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

2.2.7 Subir archivos

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

La desventaja de esto es que la ubicación de almacenamiento está codificada en la máquina local. Si quiero almacenarlo en el servidor, será difícil que otras plataformas lo manejen, así que podemos hacer esto:

# 开发环境的配置文件

# 图片保存的路径
img:
  path: D:/Training/
# 生产环境的配置文件

# 图片保存的路径
img:
  path: /root/img/

# 设置配置文件的运行平台
spring:
  profiles:
    active: dev

在不同运行平台配置文件设置:

  1. Cree diferentes archivos de configuración:
    inserte la descripción de la imagen aquíinserte la descripción de la imagen aquíinserte la descripción de la imagen aquí
    reglas de nomenclatura para archivos de configuración en diferentes plataformas: application-platform.yml (propiedades), debe nombrarse así,
  1. Establezca el archivo de configuración en ejecución en el archivo de configuración principal:
    inserte la descripción de la imagen aquí
    después de esta operación, solo necesitamos modificar el entorno correspondiente al activo, y se puede almacenar a voluntad, sin modificaciones frecuentes.

inserte la descripción de la imagen aquí

// 从配置文件中读取图片的保存路径
    @Value("${img.path}")
    private String imgPath;

    @RequestMapping("/upimg")
    public boolean upImg(Integer uid, @RequestPart("img") MultipartFile file) {
    
    
        boolean result = false;
        String fileName = file.getOriginalFilename(); // 得到原图片的名称(xxx.png)
        fileName = fileName.substring(fileName.lastIndexOf(".")); // 得到图片后缀(png)
        fileName = UUID.randomUUID().toString() + fileName;
        // 保存图片到本地目录
        try {
    
    
            file.transferTo(new File(imgPath + fileName));
            result = true;
        } catch (IOException e) {
    
    
            log.error("上传图片失败:" + e.getMessage());
        }
        return result;
    }

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

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

2.2.8 Obtener cookies

① Cómo obtiene el servlet la cookie

@RequestMapping("/cookie")
    public void getCookie(HttpServletRequest request) {
    
    
        // 得到全部的 Cookie
        Cookie[] cookies = request.getCookies();
        for (Cookie item : cookies) {
    
    
            log.info("Cookie Name:" + item.getName() +
                    " | Cookie Value:" + item.getValue());
        }
    }

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

Resultado devuelto:
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

La desventaja de esto es que todas las cookies se leen a la vez

② Use la anotación @CookieValue para leer cookies

 @RequestMapping("/cookie2")
    public String getCookie2(@CookieValue("456") String cookie) {
    
    
        return "Cookie Value:" + cookie;
    }

inserte la descripción de la imagen aquí

2.2.9 Obtener la información en el Encabezado (encabezado de solicitud)

① Método de servlet

 @RequestMapping("/getua")
    public String getHead(HttpServletRequest request) {
    
    
        return "header:" + request.getHeader("User-Agent");
    }

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

② La forma de usar la anotación @RequestHeader

@RequestMapping("/getua2")
    public String getHead2(@RequestHeader("User-Agent") String userAgent) {
    
    
        return "header:" + userAgent;
    }

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

2.2.10 Guardar Sesión

Antes de configurar (almacenar) la sesión:
inserte la descripción de la imagen aquí

Después de almacenar la sesión:

@RequestMapping("/setsess")
    public boolean setSession(HttpServletRequest request) {
    
    
        boolean result = false;
        // 1.得到 HttpSession
        HttpSession session = request.getSession(true); // true=如果没有会话,那么创建一个会话
        // 2.使用 setAtt 设置值
        session.setAttribute("userinfo", "张三");
        result = true;
        return result;
    }

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

Guarde el SessionId y páselo al servidor para obtenerlo

2.2.11 Obtener sesión

① Método de servlet

@RequestMapping("/getsess")
    public String getSession(HttpServletRequest request) {
    
    
        String result = null;
        // 1.得到 HttpSession 对象
        HttpSession session = request.getSession(false); // false=如果有会话,使用会话,如果没有,那么不会新创建会话
        // 2.getAtt 得到 Session 信息
        if (session != null && session.getAttribute("userinfo") != null) {
    
    
            result = (String) session.getAttribute("userinfo");
        }
        return "会话: "+result;
    }

先存才取:
inserte la descripción de la imagen aquí

② La forma de usar la anotación @SessionAttribute

@RequestMapping("/getsess2")
    public String getSession2(@SessionAttribute(value = "userinfo",
            required = false) String userinfo) {
    
    
        return "会话:" + userinfo;
    }

inserte la descripción de la imagen aquí

2.3 Datos de devolución

2.3.1 Volver a la página estática

Crear una página de inicio:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

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

注意:No agregué una @ResponseBodyanotación , y si la agregué, no devolvería una página estática:

2.3.2 Devolver una página no estática

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

2.3.3 Ejercicio: Implementación de la función Calculadora

código de front-end
inserte la descripción de la imagen aquí

código de fondo
inserte la descripción de la imagen aquí

resultado

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

2.3.4 Simular la función de inicio de sesión

Código front-end: enviar JSON

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="js/jquery-1.9.1.min.js"></script>
    <title>Document</title>
    <script>
        // ajax 提交
        function mysub(){
      
      
            // 1.判空
            var username = jQuery("#username");
            var password = jQuery("#password");
            if(jQuery.trim(username.val())==""){
      
      
                alert("请先输入用户名!");
                username.focus(); // 光标重制到此元素
                return;
            }
            if(jQuery.trim(password.val())==""){
      
      
                alert("请先输入密码!");
                password.focus(); // 光标重制到此元素
                return;
            }
            jQuery.ajax({
      
      
                url:"/login",
                type:"POST",
                contentType:"application/json",
                data:JSON.stringify({
      
      "username":username.val(),
                    "password":password.val()}),
                success:function(result){
      
      
                    alert(JSON.stringify(result));
                }
            });
        }
    </script>
</head>
<body>
<div style="text-align: center;">
    <h1>登录</h1>
    用户:<input id="username">
    <br>
    密码:<input id="password" type="password">
    <br>
    <input type="button" value=" 提交 " onclick="mysub()" style="margin-top: 20px;margin-left: 50px;">
</div>
</body>
</html>

inserte la descripción de la imagen aquí

Código backend: recibir JSON

 /**
     * 获取前端的 json 数据
     *
     * @param userInfo
     * @return
     */
    @RequestMapping("/login")
    public HashMap<String, Object> login(@RequestBody UserInfo userInfo) {
    
    
        HashMap<String, Object> result = new HashMap<String, Object>();
        int state = 200;
        int data = -1; // 等于 1,登录成功,否则登录失败
        String msg = "未知错误";
        if (StringUtils.hasLength(userInfo.getUsername()) && StringUtils.hasLength(userInfo.getPassword())) {
    
    
            if (userInfo.getUsername().equals("admin") && userInfo.getPassword().equals("admin")) {
    
    
                data = 1;
                msg = "";
            } else {
    
    
                msg = "用户名或密码失败!";
            }
        } else {
    
     // 参数为空
            msg = "非法参数";
        }
        result.put("state", state);
        result.put("data", data);
        result.put("msg", msg);
        return result;
    }

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

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

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

2.3.5 Solicitud de redireccionamiento y reenvío de solicitudes

① Solicitud de reenvío Reenviar

El servidor implementa el reenvío de solicitudes para el usuario

方式一:
inserte la descripción de la imagen aquíAnotación a cambiar@Controller

方式二:
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

② Solicitud de redirección Redirección

La solicitud redirigida ocurre en el lado del cliente (lado del navegador) y el lado del servidor realiza operaciones de solicitud para diferentes usuarios.

方式一:
inserte la descripción de la imagen aquíAnotación a usar@Controller

方式二:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. Resumen

3.1 Anotación combinada @RestController

@RestController = @Controller + @ResponseBody
Identifique automáticamente si devolver una página estática o una página no estática
inserte la descripción de la imagen aquí

3.2 La diferencia entre el reenvío de solicitudes (Forward) y la redirección de solicitudes (Redirect)

En Java, hay dos formas de implementar saltos: reenvío de solicitudes y redirección, que son diferentes:

  1. diferentes definiciones
  2. La fiesta de salto es diferente.
  3. Compartir datos es diferente
  4. La dirección URL final es diferente
  5. La implementación del código es diferente

1. 定义不同
Reenvío de solicitudes: ocurre dentro del programa del servidor. Cuando el servidor recibe una solicitud de un cliente, primero reenvía la solicitud a la dirección de destino y luego reenvía el resultado devuelto por la dirección de destino al cliente. ( 张三(客户端)Buscando 李四(服务器端)dinero, pero Li Si No hay tanto dinero, por lo que Li Si fue a Wang Wu a pedir dinero prestado y le dio el dinero a Zhang San. En este proceso, Zhang San equivale a pedir dinero prestado solo a Li Si)
Solicitar redirección: Solicitar redirección se refiere al servidor que recibe Después de solicitar del cliente, proporcione al cliente un encabezado de respuesta temporal, que contiene la dirección de la nueva solicitud ( 张三(客户端)buscando 李四(服务器端)dinero prestado, Li Si no lo tenía, le dijo a Zhang San: "Ve a Wang Wu para pedir prestado, no tengo dinero ahora ", por lo que Zhang San fue a Wang Wu para pedir dinero prestado)

2. 跳转方式不同
El reenvío de solicitudes es el comportamiento del servidor, el servidor envía la solicitud en lugar del cliente y devuelve el resultado al cliente; la
redirección de solicitudes es el comportamiento del cliente
inserte la descripción de la imagen aquí

3.数据共享不同
El reenvío de solicitudes se implementa en el lado del servidor. En todo el proceso de ejecución, el cliente solo necesita enviar una solicitud una vez, por lo que el mismo objeto de solicitud de solicitud y el mismo objeto de respuesta de respuesta se utilizan en todo el proceso de interacción, y todos los datos devueltos es compartida
Solicitud de redirección El cliente envía dos solicitudes completamente diferentes, y los datos en las dos solicitudes son diferentes.

4. 最终 URL 地址不同
El reenvío de solicitudes es el servidor que actúa en nombre de la solicitud y luego devuelve el resultado al cliente, por lo que la dirección URL permanece sin cambios durante todo el proceso de
solicitud; la redirección de solicitudes es decirle al cliente que vaya a otra dirección para acceder y que enviar otra solicitud, por lo que la dirección es para saltar

5. 代码实现不同
Solicitud de reenvío de
inserte la descripción de la imagen aquí
solicitud de redirección
inserte la descripción de la imagen aquí para usar @Controlleranotaciones

3.3 Implementación en caliente de IDEA (carga en caliente)

Esto es para dejarnos en el proceso de modificar el código, automáticamente detectará que el código ha sido modificado y reiniciará el proyecto Spring Boot, por lo que no tenemos que reiniciar el proyecto cada vez que queramos ver el efecto de la modificación.
1. 添加 spring boot 开发者框架支持
inserte la descripción de la imagen aquí

2. 开启 IDEA 的自动编译
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. 开启运行中的热部署
Este es el método de configuración de la versión anterior a la versión 2021.2 de IDEA
inserte la descripción de la imagen aquí

búsqueda:compiler.automake.allow.when.app.running
inserte la descripción de la imagen aquí

Versiones posteriores a IDEA 2021.2
inserte la descripción de la imagen aquí

4. 启动项目使用 debug,而不是 run 运行
Tal vez algún clic para ejecutar

inserte la descripción de la imagen aquí

Después de esta configuración, si modifica el código, no tiene que iniciarlo con frecuencia, reiniciará el proyecto cuando detecte que el código ha cambiado.

3.4 Ver más notas

API oficial: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping

Supongo que te gusta

Origin blog.csdn.net/chenbaifan/article/details/125815658
Recomendado
Clasificación