SpringBoot项目拦截器获取Post方法的请求body实现

1). 存在问题
流只能读取一次

2). 目标
多次读取流

3). 解决方法
创建包装类

4). RequestWrapper

package com.mazaiting.redeye.wrapper;
 
import com.mazaiting.redeye.utils.StreamUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
 
/***
 * @author mazaiting
 * @date 2019-06-27
 * @decription HttpServletRequest 包装器
 * 解决: request.getInputStream()只能读取一次的问题
 * 目标: 流可重复读
 */
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
    /**
     * 日志
     */
    private static final Logger mLogger = LoggerFactory.getLogger(RequestWrapper.class);
 
    /**
     * 请求体
     */
    private String mBody;
 
    public RequestWrapper(HttpServletRequest request) {
        super(request);
        // 将body数据存储起来
        mBody = getBody(request);
    }
 
    /**
     * 获取请求体
     * @param request 请求
     * @return 请求体
     */
    private String getBody(HttpServletRequest request) {
        try {
            return StreamUtil.getString(request.getInputStream());
        } catch (IOException e) {
            mLogger.debug(e.getMessage());
            throw new RuntimeException(e);
        }
    }
 
    /**
     * 获取请求体
     * @return 请求体
     */
    public String getBody() {
        return mBody;
    }
 
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
 
    @Override
    public ServletInputStream getInputStream() throws IOException {
        // 创建字节数组输入流
        final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes(Charset.defaultCharset()));
 
        return 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 bais.read();
            }
        };
    }
}

5).设置过滤器(必须)

@Component
@WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/")
@Order(10000)
public class HttpServletRequestFilter 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);
        }
        //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中
        // 在chain.doFiler方法中传递新的request对象
        if(null == requestWrapper) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            filterChain.doFilter(requestWrapper, servletResponse);
        }
    }
 
    @Override
    public void destroy() {
 
    }
}

6). 使用

/***
 *
 * @author mazaiting
 * @date 2019-06-26
 * @decription Session 拦截器
 */
public class SessionInterceptor implements HandlerInterceptor {
 
    /**
     * 日志
     */
    private static final Logger mLogger = LoggerFactory.getLogger(SessionInterceptor.class);
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        mLogger.debug("SessionInterceptor");
        // 获取地址
        String url = request.getRequestURL().toString();
        mLogger.debug("url: " + url);
        // 获取 session
        HttpSession session = request.getSession();
        String id = session.getId();
        mLogger.debug("sessionId: " + id);
        String requestMethod = request.getMethod();
        mLogger.debug("requestMethod: " + requestMethod);
        String servletPath = request.getServletPath();
        mLogger.debug("servletPath: " + servletPath);
 
        if (isJson(request)) {
            String body = new RequestWrapper(request).getBody();
            mLogger.debug("body: " + body);
        }
 
        return true;
    }
 
    /**
     * 判断本次请求的数据类型是否为json
     *
     * @param request request
     * @return true: 是 JSON 数据; false: 非 json 数据
     */
    private boolean isJson(HttpServletRequest request) {
        if (request.getContentType() != null) {
            return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) ||
                    request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE);
        }
 
        return false;
    }
}

到此这篇关于SpringBoot项目拦截器获取Post方法的请求body实现的文章就介绍到这了,更多相关SpringBoot获取Post方法的请求body内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot打印POST请求原始入参body体方式

    目录 SpringBoot打印POST请求原始入参body体 1.首先定义过滤器配置 2.实现1中的过滤器 Post接收不到body里的参数(对象参数) 检查注解 检查实体 检查Content-Type SpringBoot打印POST请求原始入参body体 1.首先定义过滤器配置 package com.choice.o2o.device.common.config; import com.choice.o2o.device.common.filter.LogFilter; import or

  • SpringBoot项目拦截器获取Post方法的请求body实现

    1). 存在问题流只能读取一次 2). 目标多次读取流 3). 解决方法创建包装类 4). RequestWrapper package com.mazaiting.redeye.wrapper;   import com.mazaiting.redeye.utils.StreamUtil; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory;   import jav

  • 教你用Springboot实现拦截器获取header内容

    分析 既然需要动态获取那么只有两种方式:要么每次下游请求过来时从请求头中获取,要么定义统一的拦截器自动获取. 实现 那么我们就先来实现一下吧. 第一种比较简单,直接使用springboot获取请求头的方式,从controller方法入口处使用: @RequestHeader(value = "xxxx",required = false) String appUser的方式获取请求头 代码如下: @RequestMapping(name = "获取用户详情信息",v

  • 拦截器获取request的值之后,Controller拿不到值的解决

    目录 拦截器获取request的值之后,Controller拿不到值 原因 解决方法 使用拦截器获取Controller方法名和注解信息 方法一:通过request获得用户的URL 方法二:通过用户要访问的方法来判断是否有权限 方法三:自定义注解 拦截器获取request的值之后,Controller拿不到值 原因 在Spring中request的值只能被获取一次,拦截器获取之后就会导致Controller拿不到值 解决方法 将request的值进行备份,请求到达Controller的时候就会拿

  • springboot config 拦截器使用方法实例详解

    本文介绍Spring-Boot中使用拦截器,一般在拦截器中处理跨域处理,允许跨域访问项目,拦截器使用详细资料请查阅官网. 实现自定义拦截器步骤: 1.创建一个类并实现HandlerInterceptor接口. 2.创建一个Java类继承WebMvcConfigurerAdapter,并重写 addInterceptors 方法. 2.将自定义的拦截器交由spring管理,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加). 创建拦截器类 package com.exam

  • springboot+mybatis拦截器方法实现水平分表操作

    目录 1.前言 2.MyBatis 允许使用插件来拦截的方法 3.Interceptor接口 4分表实现 4.1.大体思路 4.2.1 Mybatis如何找到我们新增的拦截服务 4.2.2 应该拦截什么样的对象 4.2.3 实现自定义拦截器 4.2.逐步实现 1.前言 业务飞速发展导致了数据规模的急速膨胀,单机数据库已经无法适应互联网业务的发展.由于MySQL采用 B+树索引,数据量超过阈值时,索引深度的增加也将使得磁盘访问的 IO 次数增加,进而导致查询性能的下降:高并发访问请求也使得集中式数

  • Java SpringBoot 使用拦截器作为权限控制的实现方法

    如何实现 首先拦截器是属于web这块的,那我们需要引入springboot web模块,具体版本在parent中 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 然后我们在config目录下新建interceptor目录,用来放拦截器 我们新建两

  • SpringBoot过滤器与拦截器深入分析实现方法

    目录 过滤器 编写过滤器 注册过滤器 基于 FilterRegistrationBean 基于 @WebFilter 拦截器 过滤器 实现过滤器需要实现 javax.servlet.Filter 接口.重写三个方法.其中 init() 方法在服务启动时执行,destroy() 在服务停止之前执行. 可用两种方式注册过滤器: 使用 FilterRegistrationBean 来注入.可使用 setOrder(0) 设置过滤器的优先级,越小优先级越高. 使用 @WebFilter(filterNa

  • springboot实现拦截器的3种方式及异步执行的思考

    目录 springboot 拦截器 springboot 入门案例 maven 引入 启动类 定义 Controller 拦截器定义 基于 Aspect 基于 HandlerInterceptor 基于 ResponseBodyAdvice 测试 异步执行 定义异步线程池 异步执行的 Controller 思考 测试 反思 springboot 拦截器 实际项目中,我们经常需要输出请求参数,响应结果,方法耗时,统一的权限校验等. 本文首先为大家介绍 HTTP 请求中三种常见的拦截实现,并且比较一

  • 浅谈Springboot实现拦截器的两种方式

    目录 一.拦截器方式 1.配置HandlerInterceptor 2.注册拦截器 3.使用拦截器的坑 二.过滤器方式 1.实现Filter接口 2.使用过滤器需要注意的 实现过滤请求有两种方式: 一种就是用拦截器,一种就是过滤器 拦截器相对来说比较专业,而过滤器虽然不专业但是也能完成基本的拦截请求要求. 一.拦截器方式 1.配置HandlerInterceptor 下面这个也是我们公司项目拦截器的写法,总体来说感觉还不错,我就记录了下来. 利用了一个静态Pattern变量存储不走拦截器的路径,

  • SpringBoot项目中使用AOP的方法

    本文介绍了SpringBoot项目中使用AOP的方法,分享给大家,具体如下: 1.概述 将通用的逻辑用AOP技术实现可以极大的简化程序的编写,例如验签.鉴权等.Spring的声明式事务也是通过AOP技术实现的. 具体的代码参照 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-aop Spring的AOP技术主要有4个核心概念: Pointcut: 切点,用于定义哪个方法会被拦截,例如 execution(* cn.sp

随机推荐