introduction
When using SpringMVC as the Controller layer for web development, it is often necessary to perform parameter checking on methods in Controller. Originally, SpringMVC comes with two annotations @Valid and @Validated annotations that can be used to check parameters, but it can only be checked when the parameters are beans. It is not applicable to those of String or Long. Sometimes these two annotations suddenly fail (the reasons have not been investigated carefully). In this regard, you can use Spring's AOP and custom annotations to write a parameter verification function by yourself.
Code Example
Note: The code in this section is just a demonstration, giving a feasible idea, not a complete solution.
This project is a simple web project, which is used: Spring, SpringMVC, Maven, JDK1.8
Project structure:
Custom annotations:
ValidParam.java:
package com.lzumetal.ssm.paramcheck.annotation;import java.lang.annotation.*;/** * Annotated on the parameter bean, indicating that the parameter needs to be checked*/@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ValidParam { }NotNull.java:
package com.lzumetal.ssm.paramcheck.annotation;import java.lang.annotation.*;@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface NotNull { String msg() default "Files cannot be empty"; }NotEmpty.java:
package com.lzumetal.ssm.paramcheck.annotation;import java.lang.annotation.*;@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface NotEmpty { String msg() default "Files cannot be empty"; } Face-cut
ParamCheckAspect.java:
package com.lzumetal.ssm.paramcheck.aspect;import com.lzumetal.ssm.paramcheck.annotation.NotEmpty;import com.lzumetal.ssm.paramcheck.annotation.NotNull;import com.lzumetal.ssm.paramcheck.annotation.ValidParam;import org.apache.commons.lang3.StringUtils;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.lang.reflect.Field;import java.lang.reflect.Parameter;import java.util.Arrays;/** * Parameter checking facet class */@Aspect@Componentpublic class ParamCheckAspect { @Before("execution(* com.lzumetal.ssm.paramcheck.controller.*.*(..))") public void paramCheck(JoinPoint joinPoint) throws Exception { //Get parameter object Object[] args = joinPoint.getArgs(); //Get method parameters MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Parameter[] parameters = signature.getMethod().getParameters(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; //Java's own basic types of parameters (such as Integer, String) are processed if (isPrimite(parameter.getType())) { NotNull notNull = parameter.getAnnotation(NotNull.class); if (notNull != null && args[i] == null) { throw new RuntimeException(parameter.toString() + notNull.msg()); } //TODO continue; } /* * No processing is done when the @ValidParam annotation is not marked, or when it is HttpServletRequest, HttpServletResponse, or HttpSession is not done*/ if (parameter.getType().isAssignableFrom(HttpServletRequest.class) || parameter.getType().isAssignableFrom(HttpSession.class) || parameter.getAnnotation(ValidParam.class) == null) { continue; } Class<?> paramClazz = parameter.getType(); //Get the parameter object corresponding to the type. The interface in the Controller in the actual project will not pass two parameters of the same custom type, so use findFirst() directly here. Object arg = Arrays.stream(args).filter(ar -> paramClazz.isAssignableFrom(ar.getClass())).findFirst().get(); //Get all member variables of the parameter Field[] declaredFields = paramClazz.getDeclaredFields(); for (Field field : declaredFields) { field.setAccessible(true); //Check the fields marked with @NotNull notNull = field.getAnnotation(NotNull.class); if (notNull != null) { Object fieldValue = field.get(arg); if (fieldValue == null) { throw new RuntimeException(field.getName() + notNull.msg()); } } //Check the fields marked with @NotEmpty annotation, NotEmpty is only used on String type NotEmpty notEmpty = field.getAnnotation(NotEmpty.class); if (notEmpty != null) { if (!String.class.isAssignableFrom(field.getType())) { throw new RuntimeException("NotEmpty Annotation using in a wrong field class"); } String fieldStr = (String) field.get(arg); if (StringUtils.isBlank(fieldStr)) { throw new RuntimeException(field.getName() + notEmpty.msg()); } } } } } /** * Determine whether it is a basic type: including String * @param clazz clazz * @return true: Yes; false: not */ private boolean isPrimite(Class<?> clazz){ return clazz.isPrimitive() || clazz == String.class; }} Parameters JavaBean
StudentParam.java:
package com.lzumetal.ssm.paramcheck.requestParam;import com.lzumetal.ssm.paramcheck.annotation.NotEmpty;import com.lzumetal.ssm.paramcheck.annotation.NotNull;public class StudentParam { @NotNull private Integer id; private Integer age; @NotEmpty private String name; //get, set methods omitted...} Controller for verifying parameter verification
TestController.java:
package com.lzumetal.ssm.paramcheck.controller;import com.google.gson.Gson;import com.lzumetal.ssm.paramcheck.annotation.NotNull;import com.lzumetal.ssm.paramcheck.annotation.ValidParam;import com.lzumetal.ssm.paramcheck.requestParam.StudentParam;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class TestController { private static Gson gson = new Gson(); @ResponseBody @RequestMapping(value = "/test", method = RequestMethod.POST) public StudentParam checkParam(@ValidParam StudentParam param, @NotNull Integer limit) { System.out.println(gson.toJson(param)); System.out.println(limit); return param; }} The sample code in this section has been uploaded to GitHub: https://github.com/liaosilzu2007/ssm-parent.git
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.