SpringBoot之在拦截器获取http请求的json数据公共参数的验证
时间:2019-11-25
本文章向大家介绍SpringBoot之在拦截器获取http请求的json数据公共参数的验证,主要包括SpringBoot之在拦截器获取http请求的json数据公共参数的验证使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
HTTP请求中的是字符串数据
//字符串读取 void charReader(HttpServletRequest request) { BufferedReader br = request.getReader(); String str, wholeStr = ""; while((str = br.readLine()) != null){ wholeStr += str; } System.out.println(wholeStr); } //二进制读取 void binaryReader(HttpServletRequest request) { int len = request.getContentLength(); ServletInputStream iii = request.getInputStream(); byte[] buffer = new byte[len]; iii.read(buffer, 0, len); }
注意:
request.getInputStream(); request.getReader(); 和request.getParameter("key");
这三个函数中任何一个函数执行一次后(可正常读取body数据),之后再执行就无效了,比如在Controller里面就不能再调用了。
解决方法: 包装HttpServletRequest对象,缓存body数据,再次读取的时候将缓存的值写出
新建RequestWrapper
import lombok.extern.slf4j.Slf4j; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; import java.nio.charset.Charset; /** * @description 包装HttpServletRequest,目的是让其输入流可重复读 **/ @Slf4j public class RequestWrapper extends HttpServletRequestWrapper { /** * 存储body数据的容器 */ private final byte[] body; public RequestWrapper(HttpServletRequest request) throws IOException { super(request); // 将body数据存储起来 String bodyStr = getBodyString(request); body = bodyStr.getBytes(Charset.defaultCharset()); } /** * 获取请求Body * * @param request request * @return String */ public String getBodyString(final ServletRequest request) { try { return inputStream2String(request.getInputStream()); } catch (IOException e) { log.error("", e); throw new RuntimeException(e); } } /** * 获取请求Body * * @return String */ public String getBodyString() { final InputStream inputStream = new ByteArrayInputStream(body); return inputStream2String(inputStream); } /** * 将inputStream里的数据读取出来并转换成字符串 * * @param inputStream inputStream * @return String */ private String inputStream2String(InputStream inputStream) { StringBuilder sb = new StringBuilder(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset())); String line; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { log.error("", e); throw new RuntimeException(e); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { log.error("", e); } } } return sb.toString(); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream inputStream = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return inputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } }
新建RequestWrapperFilter
import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * @description RequestWrapperFilter **/ @Slf4j @WebFilter(filterName = "requestWrapperFilter", urlPatterns = "/*") public class RequestWrapperFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("RequestWrapperFilter初始化..."); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request); chain.doFilter(requestWrapper, response); } @Override public void destroy() { log.info("RequestWrapperFilter 销毁..."); } }
springboot启动类增加@ServletComponentScan注解
在拦截器就可以获取请求参数了
新建一个拦截器ApiInterceptor
@Slf4j public class ApiInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Gson gson = new GsonBuilder().serializeNulls().enableComplexMapKeySerialization().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); String requestUrl = request.getServletPath(); String requestJson = new RequestWrapper(request).getBodyString(); Map parameterMap = gson.fromJson(requestJson, Map.class); log.info(" 请求地址为: " + requestUrl + " 请求参数为: " + requestJson); try { if (parameterMap.get("appId") == null || parameterMap.get("appId").toString() == "") { responseJson(response, gson.toJson(WrapMapper.wrap(Wrapper.ERROR_CODE, "appId 参数错误或不存在"))); return false; } return true; } catch (Exception e) { log.error(e.toString()); return false; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } private void responseJson(HttpServletResponse response, String json) throws Exception { PrintWriter writer = null; response.setCharacterEncoding("UTF-8"); response.setContentType("text/json; charset=utf-8"); try { log.info(json); writer = response.getWriter(); writer.print(json); } catch (IOException e) { log.error(e.toString()); } finally { if (writer != null) writer.close(); } } }
WebMvcConfig增加拦截器配置
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Bean public ApiInterceptor getApiInterceptor() { System.out.println("注入了 ApiInterceptor"); return new ApiInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { // 多个拦截器组成一个拦截器链 // addPathPatterns 用于添加拦截规则 // excludePathPatterns 排除拦截 String[] excludePaths = { "/login" }; registry.addInterceptor(getApiInterceptor()).addPathPatterns("/**").excludePathPatterns(Arrays.asList(excludePaths)); } }
原文地址:https://www.cnblogs.com/zengnansheng/p/11927611.html
- 剖析响应式编程的本质
- 从机器学习学python(二) ——iteritems、itemgetter、sorted、sort
- 基于MVC理解React+Redux
- JavaScript的IIFE(即时执行方法)
- 从机器学习学python(三) ——数组冒号取值与extend
- 从机器学习学python(四) ——numpy矩阵基础
- 从map函数引发的讨论
- AngularJs中,如何在render完成之后,执行Js脚本
- PHP取得上周一、上周日,下周一
- 代码诊所
- 《编程之美》读书笔记(一)——中国象棋将帅有效位置
- 有趣的Code Poster
- div 自适应高度 自动填充剩余高度
- PHP开发人员常犯的10个MysqL错误
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 解决Laravel5.2 Auth认证退出失效的问题
- php输出文字乱码的解决方法
- laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
- laravel 5.3 单用户登录简单实现方法
- Thinkphp5.0 框架的请求方式与响应方式分析
- Yii框架视图、视图布局、视图数据块操作示例
- 用php定义一个数组最简单的方法
- laravel-admin自动生成模块,及相关基础配置方法
- laravel-admin select框默认选中的方法
- Laravel-admin之修改操作日志的方法
- php使用curl伪造浏览器访问操作示例
- 关于laravel后台模板laravel-admin select框的使用详解
- 基于Laravel-admin 后台的自定义页面用法详解
- php解决约瑟夫环算法实例分析
- 浅谈laravel-admin的sortable和orderby使用问题