一.对用户输入query参数过滤空字符串
使用 WebBindingInitializer 来对string类型参数进行过滤,但是这种方式只能处理query参数不能处理body参数
代码例子:
/** * 处理String类型的请求参数,如果是空字符串则转为null,否则头尾去空 * 如果是Body,这种方式处理不了 * * @create: 2018-11-08 17:10 **/ @ControllerAdvice public class StringInitBinder { @InitBinder public void initBinder(WebDataBinder binder, WebRequest request) { binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); } }
二. 自定义Jackson ObjectMapper SimpleModule的扩展来去除@RequestBody解析实体类中字符串属性的首尾空格
/** * @Author qinming * @Description 自定义Jackson ObjectMapper SimpleModule的扩展来去除@RequestBody解析实体类中字符串属性的首尾空格 * @Date 下午6:06 2018/11/27 **/ @Component public class StringTrimModule extends SimpleModule { private static final long serialVersionUID = -1269300095841307512L; public StringTrimModule() { addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) { private static final long serialVersionUID = 1252572680057675269L; @Override public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException { return jsonParser.getValueAsString().trim(); } }); } }
三.自定义query请求参数解析
自定参数解析,需要先自定义一个注解。以ID参数解密为例进行说明:
1.自定义注解 @IdDecrypt
/** * @create: 2018-11-06 14:23 **/ @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface IdDecrypt { String value() default "AES"; }
2. 自定义参数解析
/** * ID参数解析 * **/ public class IdDecryptResolver implements HandlerMethodArgumentResolver { // 判定参数是否支持解析 @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.hasParameterAnnotation(IdDecrypt.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class); Object arg = null; String[] paramValues = request.getParameterValues(methodParameter.getParameterName()); if (paramValues != null) { arg = (paramValues.length == 1 ? paramValues[0] : paramValues); } //根据参数名称获取WebDataBinder WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest, null, methodParameter.getParameterName()); //传入解析后的值,并根据参数类型进行转换 arg = binder.convertIfNecessary(SerializerUtil.decryptAES(URLDecoder.decode(String.valueOf(arg), "UTF-8")), methodParameter.getParameterType(), methodParameter); return arg; } }
3. 在配置WebMvcConfig中添加自定义的ArgumentResolver(也就是上面的IdDecryptResolver)
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { ...... @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { //添加自定义Resolver argumentResolvers.add(new IdDecryptResolver()); super.addArgumentResolvers(argumentResolvers); } }
4. 在参数上添加该注解
@GetMapping("/info") public ApiData info(@IdDecrypt Long id) { LOGGER.info("Controller.info", "id:{}", id); return newApiData(); }
四.自定义日期参数转换
1.我这边碰到的日期转换是 时间戳 -> 日期类型 ,so我的配置是这样的
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { 。。。。。。 /** * 时间戳转日期的转换器 * * @param registry */ @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new Converter<String, Date>() { @Override public Date convert(String source) { if (StringUtils.isNotBlank(source)) { String decode = Codec.decode(source);
//正则判断时间戳参数格式 if (Pattern.compile(PatternConstant.TIME_STAMP_PATTERN).matcher(decode).matches()) { return new Date(Long.parseLong(decode)); } else { throw new RuntimeException("时间戳格式错误!"); } } return null; } }); super.addFormatters(registry); } }