拦截器中获取传递参数(解决post请求参数问题)

  1. GET中传递的参数可以直接通过request.getParameter获取。
  2. Post 传递的产生不能过直接从request.getInputStream() 读取,必须要进行重新写。(request.getInputStream()只能够读取一次)

方式: 通过重写 HttpServletRequestWrapper 类 获取getInputStream中的流数据,然后在将body数据进行重新写入传递下去。

继承 HttpServletRequestWrapper

通过重写 HttpServletRequestWrapper 类 获取getInputStream中的流数据,然后在将body数据进行重新写入传递下去。

/**
 * @author fuwenshen
 * @version 1.0.0
 * @ClassName RequestWrapper.java
 * @Description RequestWrapper封装类,
 * @createTime 2022年01月18日 13:57:00
 */
public class RequestWrapper extends HttpServletRequestWrapper {

    private String body;

    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    public RequestWrapper(HttpServletRequest request) throws IOException{
        super(request);

        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
                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) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = stringBuilder.toString();
    }


    /**
     * 重写getInputStream, 从body中获取请求参数
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
        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;
    }


    /**
     * 重写获取 字符流的方式
     * @return
     * @throws IOException
     */
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(), Charsets.UTF_8));
    }


    /**
     * 直接返回获取 body
     * @return
     */
    public String getBody() {
        return this.body;
    }
}

继承HandlerInterceptorAdapter

通过继承HandlerInterceptorAdapter实现SpringBoot 拦截器功能

  • GET中传递的参数可以直接通过request.getParameter获取。
  • Post 传递的产生不能过直接从request.getInputStream() 读取,必须要进行重新写。(request.getInputStream()只能够读取一次)
/**
 * @author fuwenshen
 * @version 1.0.0
 * @ClassName TokenValidateIntercepter.java
 * @Description token 校验拦截器
 * @createTime 2022年01月18日 13:47:00
 */
public class TokenValidateInterceptor extends HandlerInterceptorAdapter {
    private Logger logger = LoggerFactory.getLogger(TokenValidateInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("token");

        if(StrUtil.isBlank(token)){
             response.getWriter().print("token is not null");
             return false;
        }

        // 参数集合 初始化
        Map<String, Object> paramsMaps = new TreeMap();

        try {
            if ("POST".equals(request.getMethod().toUpperCase())) {
                // 防止流读取一次后就没有了, 所以需要将流继续写出去
                RequestWrapper requestWrapper = new RequestWrapper(request);
                String body = requestWrapper.getBody();
                paramsMaps = JSONObject.parseObject(body, TreeMap.class);
                logger.debug("parameterMap:" + paramsMaps.toString());
            } else {
                Map<String, String[]> parameterMap = request.getParameterMap();
                Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
                Iterator<Map.Entry<String, String[]>> iterator = entries.iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String[]> next = iterator.next();
                    paramsMaps.put(next.getKey(), next.getValue()[0]);
                }
                logger.debug("parameterMap:" + paramsMaps.toString());
            }


         // checkTokenSign
            


        }catch (Exception e){
            logger.error("token 验签失败!",e);
            return false;
        }

        return true;
    }
}
HandlerInterceptorAdapter 是 Spring MVC 提供的拦截器,可以在请求处理之前或之后对请求进行拦截和处理。 下面是一个示例,演示了如何使用 HandlerInterceptorAdapter 对 POST 请求进行拦截并重写 JSON 参数: ```java public class JsonParamInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getMethod().equals("POST")) { String contentType = request.getHeader("Content-Type"); if (contentType != null && contentType.contains("application/json")) { // 读取 JSON 参数 String json = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); JSONObject jsonObj = JSONObject.parseObject(json); // 修改 JSON 参数 jsonObj.put("newKey", "newValue"); // 重写请求参数 String newJson = jsonObj.toJSONString(); request = new CustomHttpServletRequest(request, newJson.getBytes(StandardCharsets.UTF_8)); } } return true; } private static class CustomHttpServletRequest extends HttpServletRequestWrapper { private final byte[] body; public CustomHttpServletRequest(HttpServletRequest request, byte[] body) { super(request); this.body = body; } @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStreamWrapper(body); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8)); } } private static class ServletInputStreamWrapper extends ServletInputStream { private final ByteArrayInputStream bis; public ServletInputStreamWrapper(byte[] buffer) { this.bis = new ByteArrayInputStream(buffer); } @Override public int read() throws IOException { return bis.read(); } } } ``` 上述代码,我们在 `preHandle` 方法判断请求是否为 POST 请求,并且 Content-Type 是否为 application/json。如果是,就读取 JSON 参数,并且修改其的一个字段,最后重写请求参数,然后将修改后的请求继续传递给后续的处理器。 注意,为了重写请求参数,我们需要自定义一个 HttpServletRequestWrapper,并且重写 getInputStream 和 getReader 方法。这样就可以将修改后的请求参数传递给后续的处理器了。 当然,这只是一个简单的示例,实际场景可能需要更复杂的处理逻辑。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值