解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题

时间:2025-03-20 11:39:21

原文查看:/pyxly1314/article/details/51802652

改编后:

BodyReaderHttpServletRequestWrapper类:
import ;
import ;
import ;
import ;
import ;
import ;

import javax.servlet.ServletInputStream;
import ;
import ;

/**
 * 用于将request重新进行封装
 *
 *
 */
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = (request).getBytes(("UTF-8"));
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return ();
            }
        };
    }

    @Override
    public String getHeader(String name) {
        return (name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        return ();
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        return (name);
    }
}



HttpHelper类:
import ;
import ;
import .InputStream;
import ;
import ;

import ;

/**
 * 用于将字节数组转换为字符串
 *
 *
 *
 */
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 = ();
            reader = new BufferedReader(new InputStreamReader(inputStream, ("UTF-8")));
            String line = "";
            while ((line = ()) != null) {
                (line);
            }
        } catch (IOException e) {
            ();
        } finally {
            if (inputStream != null) {
                try {
                    ();
                } catch (IOException e) {
                    ();
                }
            }
            if (reader != null) {
                try {
                    ();
                } catch (IOException e) {
                    ();
                }
            }
        }
        return ();
    }
}


自己的filter类:

import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

/**
 * 用于uerName过滤
 *
 *
 */
public class LoginFilter implements Filter {

    /*
     * (non-Javadoc)
     *
     * @see #destroy()
     */
    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     *
     * @see #doFilter(, ,
     * )
     */
    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException,
            ServletException {
        HttpServletRequest req = (HttpServletRequest) arg0;
        HttpServletResponse response = (HttpServletResponse) arg1;
        ("UTF-8");
        ("application/json; charset=utf-8");
        ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(req);
        String body = (requestWrapper);
        自己拦截的逻辑
        (requestWrapper, response);
    }

    /*
     * (non-Javadoc)
     *
     * @see #init()
     */
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }
}

对于文件来说,上述的方法不管用:

1.前言:

1.1 在使用springMVC中,需要在过滤器中获取请求中的参数token,根据token判断请求是否合法;

1.2 通过(key)方法获得参数值;

这种方法有缺陷:它只能获取  POST 提交方式中的Content-Type: application/x-www-form-urlencoded;

      HttpServletRequest request= (HttpServletRequest) req;
      String param = ("param");

2.问题:

在一般的请求中,content-type为:application/x-www-form-urlencoded;在此种请求中,使用(key)方法可以获取到key对应的属性值;

因为最近涉及到文件的上传操作,上传文件的请求中content-type为:multipart/form-data;此种请求无法直接用(key)获取对应的属性值,request中获取的属性值全部为空,无法正常获取;

在如下过滤器中,上传文件中的content-type:multipart/form-data使用获取(key)无法获取相应的值。需要借助Spring框架中的(HttpServletRequest request)将request转为MultipartHttpServletRequest,从而使用getParameter(key)方法获取指定的值;

在将对象转化完成后,要将转化完成的对象赋值给过滤链中的request参数中,即如下代码中的  req = multiReq; 赋值完成很重要,否则在controller层中依旧无法获取其他参数。

如果不需要再filter中获取请求中的值,则无需如下的操作,在请求经过springMVC框架后,自动会识别请求方式,如果是文件请求,会自动调用(HttpServletRequest request)方法转化;

原文请参考:/springlight/p/