欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

继承HttpServletRequestWrapper实现流重复读、参数过滤等场景

程序员文章站 2022-04-01 10:38:36
背景 项目基于springboot开发,RestFull接口向外暴露的API需要进行签名验证,即在进入真正controller方法前,需要先验证接口请求的有效性,所以需要对提交的POST流进行JSON读,并将相关参数进行验签。如果在Filter中使用request.getInputStream()来获取流来得到body中的信息,可以达到预期效果,但是流的获取只能获取一次,之后再获取就获取不到了,导致controller无法拿到参数而报错。参考相关资料发现实现一个类继承HttpServletReques...

背景

   项目基于springboot开发,RestFull接口向外暴露的API需要进行签名验证,即在进入真正controller方法前,需要先验证接口请求的有效性,所以需要对提交的POST流进行JSON读,并将相关参数进行验签。如果在Filter中使用request.getInputStream()来获取流来得到body中的信息,可以达到预期效果,但是流的获取只能获取一次,之后再获取就获取不到了,导致controller无法拿到参数而报错。参考相关资料发现实现一个类继承HttpServletRequestWrapper,重写其中的getInputStream方法,让其可以重复获取我们想要的流。

自定义RequestWrapper类

package com.argrace.platform.interceptor;

import com.argrace.platform.exception.VeecloudBizException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RequestWrapper extends HttpServletRequestWrapper {
   private static final Logger log = LoggerFactory.getLogger(RequestWrapper.class);
   private String mBody;

   public RequestWrapper(HttpServletRequest request) {
      super(request);
      this.mBody = this.getBody(request);
   }

   public static String convertStreamToString(InputStream is) {
      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      StringBuilder sb = new StringBuilder();

      try {
         String line;
         try {
            while((line = reader.readLine()) != null) {
               sb.append(line + "\n");
            }
         } catch (IOException var13) {
            log.error("IOException", var13);
         }
      } finally {
         try {
            is.close();
         } catch (IOException var12) {
            log.error("IOException", var12);
         }

      }

      return sb.toString();
   }

   private String getBody(HttpServletRequest request) {
      try {
         return convertStreamToString(request.getInputStream());
      } catch (IOException var3) {
         log.debug(var3.getMessage());
         throw new VeecloudBizException(var3);
      }
   }

   public String getBody() {
      return this.mBody;
   }

   public BufferedReader getReader() throws IOException {
      return new BufferedReader(new InputStreamReader(this.getInputStream()));
   }

   public ServletInputStream getInputStream() throws IOException {
      final ByteArrayInputStream bais = new ByteArrayInputStream(this.mBody.getBytes(Charset.defaultCharset()));
      return new ServletInputStream() {
         public boolean isFinished() {
            return false;
         }

         public boolean isReady() {
            return false;
         }

         public void setReadListener(ReadListener readListener) {
         }

         public int read() throws IOException {
            return bais.read();
         }
      };
   }
}

实用案例

代码块:

public void test(HttpServletRequest request, HttpServletResponse response) throws Exception {
      String param;
      if (this.isJson(request)) {
         param = (new RequestWrapper(request)).getBody();
         log.info("[test] 获取到application/json请求参数 : {}", param);
      } else {
         SortedMap<String, String> map = this.getAllParams(request);
         param = JSON.toJSONString(map);
         log.info("[test] 获取到application/x-www-form-urlencoded请求参数 : {}", param);
      }
}
private boolean isJson(HttpServletRequest request) {
      if (request.getContentType() == null) {
         return false;
      } else {
         return request.getContentType().equals("application/json") || request.getContentType().equals("application/json;charset=UTF-8");
      }
   }

本文地址:https://blog.csdn.net/keyingbo2008/article/details/107684691