El uso de JSR303 e interceptores.

1.JSR303

1. Comprenda JSR303

JSR es la abreviatura de Solicitudes de especificación de Java, que significa propuesta de especificación de Java. Es una solicitud formal a JCP (Java Community Process) para agregar una especificación técnica estandarizada. Cualquiera puede enviar un JSR para agregar nuevas API y servicios a la plataforma Java. JSR se ha convertido en un estándar importante en el mundo Java. JSR-303 es una subespecificación en JAVA EE 6 llamada Bean Validation. Hibernate Validator es la implementación de referencia de Bean Validation. Hibernate Validator proporciona la implementación de todas las restricciones integradas en la especificación JSR 303, además de algunas restricciones adicionales.

 La validación de datos es una tarea común que ocurre en todas las capas de la aplicación, desde la capa de presentación hasta la capa de persistencia. A menudo se implementa la misma lógica de validación en cada capa, lo que requiere mucho tiempo y es propenso a errores. Para evitar la duplicación de estas validaciones, los desarrolladores suelen incluir la lógica de validación directamente en el modelo de dominio, mezclando clases de dominio con código de validación que en realidad son metadatos sobre las clases mismas.

2. ¿Por qué utilizar JSR303?

¿La interfaz ya no ha verificado los datos? ¿Por qué todavía necesitamos hacer la verificación? ¿Por qué no simplemente la usamos? Es descuidado. Si la verificación del código de front-end no está bien escrita, o para las personas que saben un poco de programación, pueden omitir directamente el front-end y enviar solicitudes (realizar solicitudes de datos extraordinarias a través de herramientas de prueba como Postman) y pasar algunos errores. parámetros Ven aquí, ¿no está en peligro tu código back-end?

Por lo tanto, generalmente realizamos un conjunto de verificaciones en el front-end y un conjunto de verificaciones en el back-end, para que la seguridad pueda mejorarse enormemente.

3.Anotaciones de uso común

anotación ilustrar
@Nulo Se utiliza para verificar que el objeto es nulo.
@No nulo Se utiliza para objetos que no pueden ser nulos y no pueden verificar cadenas con una longitud de 0
@NoEnBlanco Solo se usa para el tipo String, no puede ser nulo y el tamaño después de trim()>0
@No vacío Utilizadas para clases de colección, las clases String no pueden ser nulas y el tamaño>0. Pero las cadenas con espacios no se pueden verificar.
@Tamaño Se utiliza para comprobar si la longitud del objeto (matriz, colección, mapa, cadena) está dentro del rango dado
@Longitud El tamaño utilizado para los objetos String debe estar dentro del rango especificado
@Patrón Reglas para saber si un objeto String se ajusta a una expresión regular
@Correo electrónico Se utiliza para determinar si el objeto String se ajusta al formato del buzón
@mínimo Se utiliza para determinar si los objetos Número y Cadena son mayores o iguales que el valor especificado.
@Max Se utiliza para determinar si los objetos Número y Cadena son menores o iguales que el valor especificado
@AsertTrue Si el objeto booleano es verdadero
@AssertFalse Si el objeto booleano es falso

 4. La diferencia entre @Validated y @Valid

@Validado:

  • Proporcionado por primavera

  • Verificación del grupo de apoyo

  • Se puede utilizar en tipos, métodos y parámetros de métodos. Pero no se puede utilizar en atributos de miembros (campos)

  • Dado que no se puede agregar a los atributos (campos) del miembro, la verificación en cascada no se puede completar sola y debe coordinarse con @Valid.

@Válido:

  • Proporcionado por JDK (especificación estándar JSR-303)

  • La verificación grupal no es compatible

  • Se puede utilizar en métodos, constructores, parámetros de métodos y propiedades de miembros (campos)

  • Se puede agregar a los atributos (campos) del miembro para completar la verificación en cascada de forma independiente.

5. Utilice JSR303

1. Importar dependencias de pom.xml 

<!-- JSR303 -->
<hibernate.validator.version>6.0.7.Final</hibernate.validator.version>

<!-- JSR303 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>${hibernate.validator.version}</version>
</dependency>

2. Verificación de configuración

package com.xzs.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.NotNull;

@Data//相当于set get toString方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor 
public class Clazz {
    @NotNull(message = "班级编号不能为空")
//    @Size(max = 100,min = 10,message = "大小必须在10至100之间")
    protected Integer cid;

    @NotBlank(message = "班级名不能为空")
    protected String cname;

    @NotBlank(message = "班级教员老师不能为空")
    protected String cteacher;

    private String pic="暂无图片";


}

3.Método de verificación

   @RequestMapping("/valiAdd")
    public String valiAdd(@Validated Clazz clazz, BindingResult result, HttpServletRequest req){
//        如果服务端验证不通过,有错误
        if(result.hasErrors()){
//            服务端验证了实体类的多个属性,多个属性都没有验证通过
            List<FieldError> fieldErrors = result.getFieldErrors();
            Map<String,Object> map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
//                将多个属性的验证失败信息输送到控制台
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            req.setAttribute("errorMap",map);
        }else {
            this.clazzBiz.insertSelective(clazz);
            return "redirect:list";
        }
        return "clz/edit";
    }
Interfaz
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户编辑、新增公共页面</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/${empty c ? 'clz/valiAdd' : 'clz/edit'}" method="post">
    学生id:<input type="text" name="id" value="${c.cid }"><span STYLE="color: red">${errorMap.cid}</span><br>
    学生名:<input type="text" name="name" value="${c.cname }"><span STYLE="color: red">${errorMap.cname}</span><br>
    老师:<input type="text" name="loginname" value="${c.cteacher }"><span STYLE="color: red">${errorMap.cteacher}</span><br>


    <input type="submit">
</form>
</body>
</html>

resultado:

2.interceptor

2.1.¿Qué es un interceptor?

El interceptor de procesador de SpringMVC es similar al filtro en el desarrollo de Servlet y se utiliza para preprocesar y posprocesar el procesador. Se basa en el marco web y se basa en el mecanismo de reflexión de Java en la implementación, que es una aplicación de programación orientada a aspectos (AOP). Dado que el interceptor se basa en la llamada del marco web, la inyección de dependencia (DI) de Spring se puede utilizar para realizar algunas operaciones comerciales y, al mismo tiempo, se puede llamar a una instancia de interceptor varias veces dentro del ciclo de vida del controlador.

2.2.Interceptores y filtros

¿Qué es un filtro?

Depende del contenedor de servlet. Según las devoluciones de llamadas de funciones en la implementación, casi todas las solicitudes se pueden filtrar, pero la desventaja es que una instancia de filtro solo se puede llamar una vez cuando se inicializa el contenedor. El propósito de usar filtros es realizar algunas operaciones de filtrado, tales como: modificar la codificación de caracteres en el filtro; modificar algunos parámetros de HttpServletRequest en el filtro, incluido: filtrar texto vulgar, caracteres peligrosos, etc.

 En resumen, un interceptor es un componente que intercepta y procesa solicitudes durante el procesamiento de solicitudes y se puede utilizar para implementar algunas funciones de preprocesamiento, posprocesamiento, interceptación de solicitudes y filtrado. Proporciona un mecanismo flexible para el procesamiento y control unificado de solicitudes.

La diferencia entre interceptores y filtros.

  • filtrar

    1. El filtro pertenece a la tecnología Servlet y se puede utilizar en cualquier proyecto web.

    2.filter se debe principalmente a filtrar todas las solicitudes

    3.El tiempo de ejecución del filtro es anterior al del Interceptor.

  • interceptador

    1.interceptor pertenece a la tecnología SpringMVC y debe tener un entorno SpringMVC antes de poder usarse.

    2.El interceptor generalmente intercepta el controlador del procesador.

    3.interceptor solo puede interceptar solicitudes procesadas por despachadorServlet

2.3 Escenarios de aplicación y funciones de los interceptores
Verificación de permisos: los interceptores se pueden utilizar para verificar los permisos del usuario, como verificar si el usuario ha iniciado sesión, si tiene permiso para acceder a un recurso, etc. Al interceptar solicitudes y realizar la verificación de permisos, se puede proteger la seguridad del sistema y la integridad de los datos.

Registro: los interceptores se pueden utilizar para registrar la información del registro de solicitudes y respuestas, incluida la URL solicitada, los parámetros de la solicitud, el tiempo de procesamiento, los resultados de la respuesta, etc. Al registrar registros, se puede realizar fácilmente la supervisión del sistema, la resolución de problemas y la optimización del rendimiento.

Preprocesamiento de parámetros: el interceptor puede preprocesar los parámetros de solicitud, como verificar, convertir, modificar, etc. Esto garantiza la validez y coherencia de los parámetros de solicitud y reduce la aparición de errores y excepciones.

Manejo de excepciones: los interceptores se pueden utilizar para manejar de manera uniforme las excepciones que ocurren durante el proceso de solicitud. Al interceptar excepciones y manejarlas de manera uniforme, puede proporcionar una página de aviso de error amigable o devolver información de error específica, mejorando la tolerancia a fallas del sistema y la experiencia del usuario.

Control de caché: los interceptores se pueden usar para controlar el uso del caché, como determinar si se usa el caché en función de la URL solicitada, los parámetros y otras condiciones, así como el tiempo de vencimiento del caché, etc. Al interceptar solicitudes y realizar control de caché, puede mejorar el rendimiento del sistema y la velocidad de respuesta.

Redirección de solicitudes: el interceptor puede redirigir la solicitud de acuerdo con ciertas condiciones y reenviarla a otras URL o procesadores para su procesamiento. Al interceptar solicitudes y redirigirlas, se puede lograr el reenvío de solicitudes, el enrutamiento y el control de procesos.

Procesamiento unificado: los interceptores se pueden utilizar para implementar alguna lógica de procesamiento unificado, como conversión de codificación unificada, configuración del juego de caracteres, configuración del encabezado de respuesta, etc. para solicitudes. Al interceptar solicitudes y procesarlas de manera uniforme, se puede mejorar la coherencia y la capacidad de mantenimiento del sistema.

        Los interceptores se utilizan ampliamente en el desarrollo web y pueden interceptar, procesar y modificar solicitudes e implementar funciones como verificación de permisos, registro, preprocesamiento de parámetros, manejo de excepciones, control de caché, redirección de solicitudes y procesamiento unificado. Mediante el uso de interceptores, se puede mejorar la seguridad, la estabilidad, el rendimiento y la capacidad de mantenimiento del sistema.

 Crear y usar interceptores

Flujo de trabajo del interceptor

como muestra la imagen

package com.xzs.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 OneInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【OneInterceptor】:preHandle...");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【OneInterceptor】:postHandle...");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【OneInterceptor】:afterCompletion...");
    }
}

 Configurar interceptor

<mvc:interceptors>
        <bean class="com.xzs.interceptor.OneInterceptor"></bean>
</mvc:interceptors>

prueba 

 Al enviar la solicitud podrá ver los resultados obtenidos.

Lo anterior es cómo interceptar si la interceptación no tiene éxito.

 Cambie el valor verdadero de este código a falso y la interceptación será exitosa.

Una vez que la interceptación sea exitosa, el siguiente código ya no se ejecutará.

múltiples interceptores

package com.xzs.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 TwoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【TwoInterceptor】:preHandle...");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【TwoInterceptor】:postHandle...");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【TwoInterceptor】:afterCompletion...");
    }
}

 Configuración

   <mvc:interceptors>
        <!--2) 多拦截器(拦截器链)-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.xzs.interceptor.OneInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/clz/**"/>
            <bean class="com.xzs.interceptor.TwoInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

 Como puede verse, se realizaron múltiples intercepciones cuando volví a realizar la prueba.

 Caso de interceptación de inicio de sesión

Bloqueador de inicio de sesión

package com.xzs.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 LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【implements】:preHandle...");
        StringBuffer url = request.getRequestURL();
        if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
            //        如果是 登录、退出 中的一种
            return true;
        }
//            代表不是登录,也不是退出
//            除了登录、退出,其他操作都需要判断是否 session 登录成功过
        String uname = (String) request.getSession().getAttribute("uname");
        if (uname == null || "".equals(uname)){
            response.sendRedirect("/page/login");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

Escritura frontal

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录界面</title>
</head>
<body>
<h1>登录界面</h1>
<form action="/login" method="post">
    账号:<input name="uname">
    <input type="submit">
</form>
</body>
</html>

 Inicie sesión en la capa de control de operaciones

package com.xzs.web;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(HttpServletRequest req){
        String uname = req.getParameter("uname");
        HttpSession session = req.getSession();
        if ("zs".equals(uname)){
            session.setAttribute("uname",uname);
        }
        return "redirect:/clz/list";
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest req){
        req.getSession().invalidate();
        return "redirect:/clz/list";
    }
}

prueba

No ingreses zs

Entra Zhang San. 

 

 abandonar

Supongo que te gusta

Origin blog.csdn.net/weixin_72997875/article/details/132844260
Recomendado
Clasificación