最近有一个需要从拦截器中获取post请求的参数的需求,这里记录一下处理过程中出现的问题。

首先想到的就是request.getParameter(String )方法,但是这个方法只能在get请求中取到参数,post是不行的,后来想到了使用流的方式,调用request.getInputStream()获取流,然后从流中读取参数,如下代码所示:

String body = "";

StringBuilder stringBuilder = new StringBuilder();

BufferedReader bufferedReader = null;

InputStream inputStream = null;

try {

inputStream = request.getInputStream();

if (inputStream != null) {

bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

char[] charBuffer = new char[128];

int bytesRead = -1;

while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {

stringBuilder.append(charBuffer, 0, bytesRead);

}

} else {

stringBuilder.append("");

}

} catch (IOException ex) {

e.printStackTrace();

} finally {

if (inputStream != null) {

try {

inputStream.close();

}

catch (IOException e) {

e.printStackTrace();

}

}

if (bufferedReader != null) {

try {

bufferedReader.close();

}

catch (IOException e) {

e.printStackTrace();

}

}

}

body = stringBuilder.toString();

代码中的body就是request中的参数,我这里传的是JSON数据:{"page": 1, "pageSize": 10},那么body就是:body = "{"page": 1, "pageSize": 10}",一个JSON字符串。这样是可以成功获取到post请求的body,但是,经过拦截器后,参数经过@RequestBody注解赋值给controller中的方法的时候,却抛出了一个这样的异常:

org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

在网上查找资料后发现,request的输入流只能读取一次,那么这是为什么呢?下面是答案:

那是因为流对应的是数据,数据放在内存中,有的是部分放在内存中。read 一次标记一次当前位置(mark position),第二次read就从标记位置继续读(从内存中copy)数据。 所以这就是为什么读了一次第二次是空了。 怎么让它不为空呢?只要inputstream 中的pos 变成0就可以重写读取当前内存中的数据。javaAPI中有一个方法public void reset() 这个方法就是可以重置pos为起始位置,但是不是所有的IO读取流都可以调用该方法!ServletInputStream是不能调用reset方法,这就导致了只能调用一次getInputStream()。

那么有什么办法可以用户解决呢?上面这篇博客中提到了解决方案,就是重写HttpServletRequestWrapper把request保存下来,然后通过过滤器把保存下来的request再填充进去,这样就可以多次读取request了。步骤如下所示:

①写一个类,继承HttpServletRequestWrapper

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import java.io.*;

public class RequestWrapper extends HttpServletRequestWrapper {

private final String body;

public RequestWrapper(HttpServletRequest request) {

super(request);

StringBuilder stringBuilder = new StringBuilder();

BufferedReader bufferedReader = null;

InputStream inputStream = null;

try {

inputStream = request.getInputStream();

if (inputStream != null) {

bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

char[] charBuffer = new char[128];

int bytesRead = -1;

while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {

stringBuilder.append(charBuffer, 0, bytesRead);

}

} else {

stringBuilder.append("");

}

} catch (IOException ex) {

} finally {

if (inputStream != null) {

try {

inputStream.close();

}

catch (IOException e) {

e.printStackTrace();

}

}

if (bufferedReader != null) {

try {

bufferedReader.close();

}

catch (IOException e) {

e.printStackTrace();

}

}

}

body = stringBuilder.toString();

}

@Override

public ServletInputStream getInputStream() throws IOException {

final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());

ServletInputStream servletInputStream = new ServletInputStream() {

@Override

public boolean isFinished() {

return false;

}

@Override

public boolean isReady() {

return false;

}

@Override

public void setReadListener(ReadListener readListener) {

}

@Override

public int read() throws IOException {

return byteArrayInputStream.read();

}

};

return servletInputStream;

}

@Override

public BufferedReader getReader() throws IOException {

return new BufferedReader(new InputStreamReader(this.getInputStream()));

}

public String getBody() {

return this.body;

}

}

②拦截器层面

package com.miniprogram.web.douyin.interceptor;

import com.alibaba.fastjson.JSON;

import com.miniprogram.api.douyin.user.req.DyuserReq;

import com.miniprogram.common.auth.VisitLimitCount;

import com.miniprogram.common.cache.RedisCache;

import com.miniprogram.common.config.InterceptorConfigMap;

import com.miniprogram.common.config.InterceptorUrlConfig;

import com.miniprogram.common.douyin.SearchEngineMapConstants;

import com.miniprogram.common.response.Response;

import com.miniprogram.common.session.*;

import com.miniprogram.common.utils.DateUtil;

import com.miniprogram.dao.common.UserLoginEntity.Users;

import com.miniprogram.service.douyin.users.UsersService;

import com.miniprogram.web.douyin.config.RequestWrapper;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.BeanUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

@Component("authSecurityInterceptor")

public class AuthSecurityInterceptor extends HandlerInterceptorAdapter {

private Logger logger = LoggerFactory.getLogger(AuthSecurityInterceptor.class);

@Autowired

private UsersService douYinUsersService;

@Autowired

private RedisCache redisCache;

@Autowired

private VisitLimitCount visitLimitCount;

@Override

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

try {

RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);

String body = requestWrapper.getBody();

System.out.println(body);

return true;

}catch (Exception e){

logger.error("权限判断出错",e);

}

return false;

}

@Override

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}

③过滤器Filter,用来把request传递下去

import com.miniprogram.web.douyin.config.RequestWrapper;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

@Component

@WebFilter(urlPatterns = "/*",filterName = "channelFilter")

public class ChannelFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

ServletRequest requestWrapper = null;

if(servletRequest instanceof HttpServletRequest) {

requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);

}

if(requestWrapper == null) {

filterChain.doFilter(servletRequest, servletResponse);

} else {

filterChain.doFilter(requestWrapper, servletResponse);

}

}

@Override

public void destroy() {

}

}

④在启动类中注册拦截器

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.web.servlet.MultipartConfigFactory;

import org.springframework.boot.web.servlet.ServletComponentScan;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

@SpringBootApplication

@ServletComponentScan //注册过滤器注解

@Configuration

public class WebApplication {

public static void main(String[] args) {

SpringApplication.run(WebApplication.class, args);

}

}

经测试,问题解决

java 拦截器响应中取所有参数,spring boot拦截器中获取request post请求中的参数相关推荐

  1. Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空

    Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空 一.问题描述 在Spring Boot的web ...

  2. 拦截器获取请求参数post_spring boot拦截器中获取request post请求中的参数

    最近有一个需要从拦截器中获取post请求的参数的需求,这里记录一下处理过程中出现的问题. 首先想到的就是request.getParameter(String )方法,但是这个方法只能在get请求中取 ...

  3. spring boot拦截器中获取request post请求中的参数(转)

    文章转自 https://www.jianshu.com/p/69c6fba08c92 转载于:https://www.cnblogs.com/shuaiandjun/p/10306242.html

  4. java 从数据库取值_JAVA操作数据库--从一张表中取值,经过判断,然后插入另一张表中。...

    JAVA操作数据库-->从一张表中取值,经过判断,然后插入另一张表中. SQL语句如下:两张表 weather 和 weather_process. id均为自动增长.Oracle中采用序列 S ...

  5. 使用spring boot拦截器实现青少年模式

    思路方法一: 便用Spring Boot拦截器采累计在线时间采实现青少年模式的步骤,可以参考以卜步骤: 1.创建一个拦截器类,实现Handlerlnterceptor 接口. 2.在拦截器类中,定义一 ...

  6. Spring Boot 拦截器无效,不起作用

    这个问题一般是解决WebMvcConfigurerAdapter过时问题造成的.导致这个问题可能有两个原因:一个是拦截器写错了,另一个是拦截器配置错了. 1.需求是这样的 拦截所有的api请求,判断其 ...

  7. Spring boot拦截器登录检查

    拦截器 进行登录检查 从登录页面跳转到成功页面之后 为了防止表单重复提交 配置视图映射,利用重定向到成功页面 此时,在浏览器直接输入,配置的视图映射地址 也可以直接映射.跳转到成功页面 登录页面,也就 ...

  8. 获取referer中的请求参数_Servlet获取AJAX POST请求中参数以form data和request payload形式传输的方法...

    本文实例讲述了Servlet获取AJAX POST请求中参数以form data和request payload形式传输的方法.分享给大家供大家参考,具体如下: HTTP请求中,如果是get请求,那么 ...

  9. Spring Boot拦截器(WebMvcConfigurerAdapter)

    直接按我的步骤走都没有问题: 1 配置自定义的拦截器: package com.configs;import org.slf4j.Logger; import org.slf4j.LoggerFact ...

最新文章

  1. Go-Mega Tutorial 01 - Hello World
  2. Java将中文姓名转换为拼音
  3. Linux下运行jar程序
  4. spring5新特性的介绍
  5. 10.13 上午 考试
  6. spring 自定义日志_Spring和Hibernate的自定义审核日志
  7. Lambda 表达式详解~简化匿名内部类
  8. windows开代理服务器
  9. LOJ10099矿场搭建
  10. java calendar时间计算_Java Calendar计算所在时区的时间偏移量
  11. Banner打造广告自动轮播图
  12. android 手势识别 (缩放 单指滑动 多指滑动)
  13. Adguard Home最低DNS处理时间配置
  14. 对于TextView中设置艺术字体
  15. linkerd1.6 local安装方式文档
  16. 【NLP】文本匹配——Simple and Effective Text Matching with Richer Alignment Features阅读与总结(RE2)
  17. 【天光学术】中国哲学论文:以老子为例看中国哲学的思辨体系
  18. 【蓝桥杯省赛真题32】Scratch帆船运动 少儿编程scratch蓝桥杯省赛真题讲解
  19. 关于两RS485系统共地的问题
  20. 报错:java.io.NotSerializableException: com.kuang.pojo.User

热门文章

  1. dedecms后台验证码错误的解决方法
  2. 苹果下架360的硅谷解读
  3. 神不知鬼不觉地置换 XP用户密码
  4. 定义一个数组返回最大子数组的值(1)
  5. Python函数默认参数陷阱
  6. Ajax实现直链(点击量统计)
  7. 代码审计之Catfish CMS v4.5.7后台作者权限越权两枚+存储型XSS一枚
  8. 《Spring Boot官方文档》16. 自动配置
  9. [Python爬虫] 之十二:Selenium +phantomjs抓取中的url编码问题
  10. mysql5.5以上my.ini中设置字符集