SpringBoot RequestBodyAdvice参数处理
在实际项目中 , 往往需要对请求参数做一些统一的操作 , 例如参数的过滤 , 字符的编码 , 第三方的解密等等 , Spring提供了RequestBodyAdvice一个全局的解决方案 , 免去了我们在Controller处理的繁琐 .
RequestBodyAdvice仅对使用了@RqestBody注解的生效 , 因为它原理上还是AOP , 所以GET方法是不会操作的.
package com.xbz.common.web; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; /** * @title 全局请求参数处理类 * @author Xingbz * @createDate 2019-8-2 */ @ControllerAdvice(basePackages = "com.xbz.controller")//此处设置需要当前Advice执行的域 , 省略默认全局生效 public class GlobalRequestBodyAdvice implements RequestBodyAdvice { /** 此处如果返回false , 则不执行当前Advice的业务 */ @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { // return methodParameter.getMethod().isAnnotationPresent(XXApiReq.class); return false; } /** * @title 读取参数前执行 * @description 在此做些编码 / 解密 / 封装参数为对象的操作 * * */ @Override public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { return new XHttpInputMessage(inputMessage, "UTF-8"); } /** * @title 读取参数后执行 * @author Xingbz */ @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return inputMessage; } /** * @title 无请求时的处理 */ @Override public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return body; } } //这里实现了HttpInputMessage 封装一个自己的HttpInputMessage class XHttpInputMessage implements HttpInputMessage { private HttpHeaders headers; private InputStream body; public XHttpInputMessage(HttpInputMessage httpInputMessage, String encode) throws IOException { this.headers = httpInputMessage.getHeaders(); this.body = encode(httpInputMessage.getBody(), encode); } private InputStream encode(InputStream body, String encode) { //省略对流进行编码的操作 return body; } @Override public InputStream getBody() { return body; } @Override public HttpHeaders getHeaders() { return null; } }
Spring默认提供了接口的抽象实现类RequestBodyAdviceAdapter , 我们可以继承这个类按需实现 , 让代码更简洁一点
package org.springframework.web.servlet.mvc.method.annotation; import java.io.IOException; import java.lang.reflect.Type; import org.springframework.core.MethodParameter; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.lang.Nullable; public abstract class RequestBodyAdviceAdapter implements RequestBodyAdvice { @Override public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { return inputMessage; } @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return body; } @Override @Nullable public Object handleEmptyBody(@Nullable O<i style="color:transparent">本文来源gaodai$ma#com搞$$代**码)网8</i>bject body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return body; } }