几品飞车|SpringBoot 拦截器获取http请求参数( 二 )
对于MVC的过滤器来说 , 我们就需要重写 ServletInputStream 的 getInputStream()方法 。
自定义 HttpServletRequestWrapper为了 重写 ServletInputStream 的 getInputStream()方法 , 我们需要自定义一个 HttpServletRequestWrapper :
【几品飞车|SpringBoot 拦截器获取http请求参数】/*** @author Axin* @summary 自定义 HttpServletRequestWrapper 来包装输入流*/public class AxinHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** 缓存下来的HTTP body*/private byte[] body;public AxinHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);body = StreamUtils.copyToByteArray(request.getInputStream());}/*** 重新包装输入流* @return* @throws IOException*/@Overridepublic ServletInputStream getInputStream() throws IOException {InputStream bodyStream = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic int read() throws IOException {return bodyStream.read();}/*** 下面的方法一般情况下不会被使用 , 如果你引入了一些需要使用ServletInputStream的外部组件 , 可以重点关注一下 。* @return*/@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setReadListener(ReadListener readListener) {}};}@Overridepublic BufferedReader getReader() throws IOException {InputStream bodyStream = new ByteArrayInputStream(body);return new BufferedReader(new InputStreamReader(getInputStream()));}}然后定义一个 DispatcherServlet子类来分派 上面自定义的 AxinHttpServletRequestWrapper :
/*** @author Axin* @summary 自定义 DispatcherServlet 来分派 AxinHttpServletRequestWrapper*/public class AxinDispatcherServlet extends DispatcherServlet {/*** 包装成我们自定义的request* @param request* @param response* @throws Exception*/@Overrideprotected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {super.doDispatch(new AxinHttpServletRequestWrapper(request), response);}}然后配置一下:
/** * WebMVC配置 , 你可以集中在这里配置拦截器、过滤器、静态资源缓存等 */@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");}@Bean@Qualifier(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServlet dispatcherServlet() {return new AxinDispatcherServlet();}}再调用一下 POST请求:
请求成功!
总结一下 展望一下如果你想对HTTP请求做些骚操作 , 那么前置获取HTTP请求参数是前提 , 为此文本给出了使用MVC拦截器获取参数的样例 。
在获取HTTP Body 的时候 , 出现了 Required request body is missing 的错误 , 同时拦截器还出现执行了两遍的问题 , 这是因为 ServletInputStream被读取了两遍导致的 , tomcat截取到异常后就转发到 /error 页面 被拦截器拦截到了 , 拦截器也就执行了两遍 。
为此我们通过自定义 HttpServletRequestWrapper 来包装一个可被重读读取的输入流 , 来达到期望的拦截效果 。
推荐阅读
- ZAKER|柬埔寨两名飞车党抢劫失手遭民众痛殴!
- QQ飞车|宁清把云海压的“手抖”,QG无情零封AG,进总决赛有望蝉联 冠军
- 九游网|《QQ飞车》手游迪迦联动活动什么时候出 迪迦联动活动内容曝光
- 绝地养鸡王|《天天飞车》发布停服公告,看到补偿礼包后,老玩家“泪目”了!
- 几品飞车苹果火力全开,iPhone12五千多起步,国产旗舰压力巨大?
- 嘻哈飞车族腻害,高人都是这样玩SpringBoot整合RabbitMQ
- 几品飞车|Excel的数据可视化和Python的有什么不同?
- QQ飞车手游S联赛|季后赛|10月17日对阵看点 昨日精彩赛况回顾
- 嘻哈飞车族|“文案界扛把子”翻车了?,杜蕾斯文案再度引爆热议
- 几品飞车Excel的数据可视化和Python的有什么不同?
