如下:开发过程中,你可能会使用RequestParam注解,设置required = true,告诉前端这个参数是必传的,
但是用过的基本了解,通常会因为前端传了空字符串,导致校验通过,实用性不佳,
原生的注解基本不能满足实际开发需求,所以你需要自己写一个。
@ResponseBody @RequestMapping("/data") public Map<String, Object> data( @RequestParam(required = true) String b) { return new HashMap<>(); }
HandlerMethodArgumentResolver
此时你需要写一个切面,HandlerMethodArgumentResolver,直译是,处理函数参数的分解器,实现这个接口也很简单,
supportsParameter(支持参数):可以设置一些标志,表示你这个分解器可以处理这些参数,返回ture才执行resolveArgument()函数
resolveArgument(分解实参):处理实参的具体方法
import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; /** * Created by 12614 on 2018/5/11. */ public class TestArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { return true; } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { System.out.println("TestArgumentResolver:resolveArgument"); return null; } }
Spring配置
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="xxxxx全类名"/> </mvc:argument-resolvers> </mvc:annotation-driven>
SpringBoot配置
既然要零配置,就不要违背设计初衷刻意去启用Xml配置,在WebMvcConfigurerAdapter添加HandlerMethodArgumentResolver就好了 ,
import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.List; /** * Created by 12614 on 2018/5/11. */ @Configuration public class ApplicationConfigurer extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { super.addArgumentResolvers(argumentResolvers); argumentResolvers.add(new TestArgumentResolver()); } }
简单的案例
自定义注解
import java.lang.annotation.*; /** * Created by 12614 on 2018/5/11. */ @Documented @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Params { @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; boolean required() default true; boolean notEmpty() default true; int maxLength() default Integer.MAX_VALUE; String defaultValue() default " ue000ue001ue002 "; }
参数分解器
未包含全部代码
import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import javax.servlet.http.HttpServletRequest; /** * Created by 12614 on 2018/5/11. */ public class TestArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { //如果函数包含我们的自定义注解,那就走resolveArgument()函数 return methodParameter.hasParameterAnnotation(Params.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { System.out.println("TestArgumentResolver:resolveArgument"); Params params = methodParameter.getParameterAnnotation(Params.class); String paramName = params.name(); if (paramName == null) { paramName = methodParameter.getParameterName(); } //简单的案例:如果客户端未传值,就设置默认值 Object res = nativeWebRequest.getNativeRequest(HttpServletRequest.class).getParameter(paramName); return res == null ? params.defaultValue() : res; } }
使用场景
@ResponseBody @RequestMapping("/data") public Map<String, Object> data( @Params(notEmpty = true,maxLength = 30, defaultValue = "aaa") String a) { System.out.println(a); return null; }