SpringBoot 解决HttpServletRequest只能读取一次
业务逻辑,通过filter读取请求的request,获取token,并将token传递后面流程使用
BodyReaderHttpServletRequestWrapper:
- public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
- private final byte[] body;
- public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
- super(request);
- body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
- }
- @Override
- public BufferedReader getReader() throws IOException {
- return new BufferedReader(new InputStreamReader(getInputStream()));
- }
- @Override
- public ServletInputStream getInputStream() throws IOException {
- final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
- return new ServletInputStream() {
- @Override
- public int read() throws IOException {
- return byteArrayInputStream.read();
- }
- @Override
- public boolean isFinished() {
- return false;
- }
- @Override
- public boolean isReady() {
- return false;
- }
- @Override
- public void setReadListener(ReadListener readListener) {
- }
- };
- }
- }
RepeatReadFilter:
- /**
- * 封装HttpServletRequest为可重复读取请求
- **/
- public class RepeatReadFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- // 防止流读取一次后就没有了, 所以需要将流继续写出去
- ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
- //获取用户凭证
- String token = httpServletRequest.getHeader(Constants.USER_TOKEN);
- if(StringUtils.isBlank(token)){
- token = httpServletRequest.getParameter(Constants.USER_TOKEN);
- }
- //=================获取json格式的token字段=========================
- String body = HttpHelper.getBodyString(requestWrapper);
- if (StringUtils.isNotBlank(body)) {
- JSONObject jsonObject = JSONObject.parseObject(body);
- Object obj = jsonObject.get("token");
- if (null != obj) {
- token = obj.toString();
- }
- }
- requestWrapper.setAttribute(Constants.USER_TOKEN,token);
- chain.doFilter(requestWrapper, response);
- }
- @Override
- public void destroy() {
- }
- }
FilterConfig:
- @Configuration
- public class FilterConfig {
- @Bean
- public FilterRegistrationBean registFilter() {
- FilterRegistrationBean registration = new FilterRegistrationBean();
- registration.setFilter(new RepeatReadFilter());
- registration.addUrlPatterns("/app/*");
- registration.setName("UrlFilter");
- registration.setOrder();
- return registration;
- }
- }
AuthorizationInterceptor:
- @Component
- public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- AuthIgnore annotation;
- if(handler instanceof HandlerMethod) {
- annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
- }else{
- return true;
- }
- //如果有@AuthIgnore注解,则不验证token
- if(annotation != null){
- return true;
- }
- //获取用户凭证
- String token = request.getHeader(Constants.USER_TOKEN);
- if(StringUtils.isBlank(token)){
- token = request.getParameter(Constants.USER_TOKEN);
- }
- if(StringUtils.isBlank(token)){
- Object obj = request.getAttribute(Constants.USER_TOKEN);
- if(null!=obj){
- token=obj.toString();
- }
- }
- //token凭证为空
- if(StringUtils.isBlank(token)){
- throw new AuthException(Constants.USER_TOKEN + "不能为空", HttpStatus.UNAUTHORIZED.value());
- }
- return true;
- }
- }
WebMvcConfig:
- @Configuration
- public class WebMvcConfig extends WebMvcConfigurerAdapter {
- @Autowired
- private AuthorizationInterceptor authorizationInterceptor;
- // @Autowired
- // private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(authorizationInterceptor).addPathPatterns("/**");
- super.addInterceptors(registry);
- }
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
- //argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
- }
- @Override
- public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
- super.configureMessageConverters(converters);
- }
- @Override
- public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
- }
- }
在filter中读取token,在interceptor中进行读取判断使用
HttpHelper:
- public class HttpHelper {
- /**
- * 获取请求Body
- *
- * @param request
- * @return
- */
- public static String getBodyString(ServletRequest request) {
- StringBuilder sb = new StringBuilder();
- InputStream inputStream = null;
- BufferedReader reader = null;
- try {
- inputStream = request.getInputStream();
- reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
- String line = "";
- while ((line = reader.readLine()) != null) {
- sb.append(line);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return sb.toString();
- }
- }
https://blog.csdn.net/beflyabot/article/details/78053130
https://my.oschina.net/vernon/blog/363693
SpringBoot 解决HttpServletRequest只能读取一次的更多相关文章
- 解决HttpServletRequest的输入流只能读取一次的问题
背景 通常对安全性有要求的接口都会对请求参数做一些签名验证,而我们一般会把验签的逻辑统一放到过滤器或拦截器里,这样就不用每个接口都去重复编写验签的逻辑. 在一个项目中会有很多的接口,而不同的接口可能接 ...
- 大白话讲解如何解决HttpServletRequest的请求参数只能读取一次的问题
大家在开发过程中,可能会遇到对请求参数做下处理的场景,比如读取上送的参数中看调用方上送的系统编号是否是白名单里面的(更多的会用request中获取IP地址判断).需要对请求方上送的参数进行大小写转换或 ...
- springboot请求体中的流只能读取一次的问题
场景交代 在springboot中添加拦截器进行权限拦截时,需要获取请求参数进行验证.当参数在url后面时(queryString)获取参数进行验证之后程序正常运行.但是,当请求参数在请求体中的时候, ...
- 解决SpringMVC拦截器中Request数据只能读取一次的问题
解决SpringMVC拦截器中Request数据只能读取一次的问题 开发项目中,经常会直接在request中取数据,如Json数据,也经常用到@RequestBody注解,也可以直接通过request ...
- 解决spring http输入流和输出流只能读取一次
1.需求:给某些请求接口记录日志,记录请求的数据和响应的数据和请求所花费的时间.这里采用非侵入式编程,也业务代码进行解耦.按照spring AOP 的编程思想. 2.编程设计:在spring 拦截器中 ...
- httpServletRequest中的流只能读取一次的原因
首先,我们复习一下InputStream read方法的基础知识, java InputStream read方法内部有一个,postion,标志当前流读取到的位置,每读取一次,位置就会移动一次,如果 ...
- request.getInputStream() 流只能读取一次问题
问题: 一次开发过程中同事在 sptring interceptor 中获取 request body 中值,以对数据的校验和预处理等操作 .导致之后spring 在读取request body 值做 ...
- 关于springboot配置文件的另类读取方法
一.背景故事 前阵子我接手了公司另外一个同事手里的项目,项目是用的springboot 写的,但是比较坑的就是这个项目写的有点不伦不类.虽然是用的springboot,但由于他是拿了一堆代码拼凑起 ...
- Request.getInputStrema只能读取一次的分析过程
1. 我们先来看一下继承关系HttpServletRequest 接口继承ServletRequest接口 public abstract interface ServletRequest{ pub ...
随机推荐
- fzu2204 dp
2015-10-06 19:31:05 n个有标号的球围成一个圈.每个球有两种颜色可以选择黑或白染色.问有多少种方案使得没有出现连续白球7个或连续黑球7个. 每组包含n,表示球的个数.(1 <= ...
- 利用QPainter绘制散点图
[1]实例代码 (1)代码目录结构(备注:QtCreator默认步骤新建工程) (2)工程pro文件 QT += core gui greaterThan(QT_MAJOR_VERSION, ): Q ...
- 调用微信JS-SDK配置签名
前后端进行分开开发: 1:后端实现获取 +++接口凭证:access_token (公众号的全局唯一接口调用凭据) ** GET 获取:https://api.weixin.qq.com/cgi-bi ...
- Linux服务器---邮件服务器dovecot
安装dovecot Dovecot是CentOS系统中著名的POP3/IMAP服务器实现.POP3/IMAP是从邮件服务器中读取邮件时使用的协议,POP3将邮件全部从服务器中拖取下来:IMAP则每次从 ...
- IPERF 网络性能测试
Iperf 是一个网络性能测试工具.Iperf可以测试最大TCP和UDP带宽性能.Iperf具有多种参数和UDP特性,可以根据需要调整.Iperf可以报告带宽,延迟抖动和数据包丢失. Iperf 参数 ...
- python--元组tuple
元组与列表一样,都是序列.但元组不能修改内容(列表允许) 默认的,元组通过圆括号括起来 1. 使用type函数查看类型 numbers = (1,2,3,4,5,6,7,8,9,0) print(ty ...
- SQL SERVER镜像配置(包含见证服务器)
镜像简介 重要说明:保持数据库镜像运行.如果您关闭数据库镜像,则必须执行完全备份并还原数据库以重建数据库镜像. 一. 简介 SQL SERVER 2005镜像基于日志同步,可良好实现故障转移. ...
- MyBatis中的if写法
<if test="latn_id !=null and latn_id !='' and latn_id !='100'"> and latnid=#{latn_id ...
- 018.07 New BMW ICOM A3+B+C+D Plus EVG7 Controller Tablet PC with WIFI Function
2018.07 New BMW ICOM A3+B+C+D Plus EVG7 Controller Tablet PC with WIFI Function Software Version : ...
- 一个六年Java程序员的从业总结:比起掉发,我更怕掉队
我一直担惊受怕,过去,可能是因为我年轻,但现在,我已经不是那么年轻了,我仍然发现有很多事情让我害怕. 当年纪越来越大后,我开始变得不能加班.我开始用更多的时间和家人在一起,而不是坐在计算机前(尽管这样 ...