HttpServletRequestWrapper中方法未调用 @Controller获取仍为原数据

写了一个filter,原始request用HttpServletRequestWrapper包装了一下,但是发现HttpServletRequestWrapper的getInputStream和getReader都没有被调用,导致数据到了controller依旧是加密状态,请问大神这个是什么原因!

在网上找到类似代码,望大神解答! https://segmentfault.com/q/1010000004149031

一般我们会在InterceptorAdapter拦截器中对请求的token进行验证
如果是content-type 是 application/x-www-form-urlencoded 则没有什么问题

如果我们的接口是用@RequestBody来接受数据,那么我们在拦截器中验证token时

需要读取request的输入流 ,因为 ServletRequest中getReader()和getInputStream()只能调用一次

这样就会导致controller 无法拿到数据。

解决方法 :

自定义一个类 BodyReaderHttpServletRequestWrapper.java

[java] view plain copy 在CODE上查看代码片派生到我的代码片
import java.io.BufferedInputStream;

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.net.URLDecoder;

import java.util.Collections;

import java.util.Enumeration;

import java.util.HashMap;

import java.util.Map;

import java.util.StringTokenizer;

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import com.microdata.core.util.Encodes;

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

private Map paramsMap;

    @Override  
    public Map getParameterMap() {  
        return paramsMap;  
    }  

    @Override  
    public String getParameter(String name) {// 重写getParameter,代表参数从当前类中的map获取  
        String[] values = paramsMap.get(name);  
        if (values == null || values.length == 0) {  
            return null;  
        }  
        return values[0];  
    }  

    @Override  
    public String[] getParameterValues(String name) {// 同上  
        return paramsMap.get(name);  
    }  

    @Override  
    public Enumeration getParameterNames() {  
        return Collections.enumeration(paramsMap.keySet());  
    }  

    private String getRequestBody(InputStream stream) {  
        String line = "";  
        StringBuilder body = new StringBuilder();  
        int counter = 0;  

        // 读取POST提交的数据内容  
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));  
        try {  
            while ((line = reader.readLine()) != null) {  
                if (counter > 0) {  
                    body.append("rn");  
                }  
                body.append(line);  
                counter++;  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  

        return body.toString();  
    }  

    private HashMap<String, String[]> getParamMapFromPost(HttpServletRequest request) {  

        String body = "";  
        try {  
            body = getRequestBody(request.getInputStream());  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        HashMap<String, String[]> result = new HashMap<String, String[]>();  

        if (null == body || 0 == body.length()) {  
            return result;  
        }  

        return parseQueryString(body);  
    }  

    // 自定义解码函数  
    private String decodeValue(String value) {  
        if (value.contains("%u")) {  
            return Encodes.urlDecode(value);  
        } else {  
            try {  
                return URLDecoder.decode(value, "UTF-8");  
            } catch (UnsupportedEncodingException e) {  
                return "";// 非UTF-8编码  
            }  
        }  
    }  

    public HashMap<String, String[]> parseQueryString(String s) {  
        String valArray[] = null;  
        if (s == null) {  
            throw new IllegalArgumentException();  
        }  
        HashMap<String, String[]> ht = new HashMap<String, String[]>();  
        StringTokenizer st = new StringTokenizer(s, "&");  
        while (st.hasMoreTokens()) {  
            String pair = (String) st.nextToken();  
            int pos = pair.indexOf('=');  
            if (pos == -1) {  
                continue;  
            }  
            String key = pair.substring(0, pos);  
            String val = pair.substring(pos + 1, pair.length());  
            if (ht.containsKey(key)) {  
                String oldVals[] = (String[]) ht.get(key);  
                valArray = new String[oldVals.length + 1];  
                for (int i = 0; i < oldVals.length; i++) {  
                    valArray[i] = oldVals[i];  
                }  
                valArray[oldVals.length] = decodeValue(val);  
            } else {  
                valArray = new String[1];  
                valArray[0] = decodeValue(val);  
            }  
            ht.put(key, valArray);  
        }  
        return ht;  
    }  

    private Map<String, String[]> getParamMapFromGet(HttpServletRequest request) {  
        return parseQueryString(request.getQueryString());  
    }  

    private final byte[] body; // 报文  

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {  
        super(request);  
        body = readBytes(request.getInputStream());  

        // 首先从POST中获取数据  
        if ("POST".equals(request.getMethod().toUpperCase())) {  
            paramsMap = getParamMapFromPost(this);  
        } else {  
            paramsMap = getParamMapFromGet(this);  
        }  

    }  

    @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 bais.read();  
            }  

            @Override  
            public boolean isFinished() {  
                return false;  
            }  

            @Override  
            public boolean isReady() {  
                return false;  
            }  

            @Override  
            public void setReadListener(ReadListener arg0) {  

            }  
        };  
    }  

    private static byte[] readBytes(InputStream in) throws IOException {  
        BufferedInputStream bufin = new BufferedInputStream(in);  
        int buffSize = 1024;  
        ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);  

        byte[] temp = new byte[buffSize];  
        int size = 0;  
        while ((size = bufin.read(temp)) != -1) {  
            out.write(temp, 0, size);  
        }  
        bufin.close();  

        byte[] content = out.toByteArray();  
        return content;  
    }  

}

自定义Filter HttpServletRequestReplacedFilter.java

[java] view plain copy 在CODE上查看代码片派生到我的代码片
import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import com.microdata.core.request.BodyReaderHttpServletRequestWrapper;

public class HttpServletRequestReplacedFilter implements Filter {

@Override

public void destroy() {

}  

@Override  
public void doFilter(ServletRequest request, ServletResponse response,  
        FilterChain chain) throws IOException, ServletException {  

    ServletRequest requestWrapper = null;  
    if (request instanceof HttpServletRequest) {  
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;  
        if ("POST".equals(httpServletRequest.getMethod().toUpperCase())  
                && httpServletRequest.getContentType().equalsIgnoreCase(  
                        "application/json; charset=utf-8")) {  
            requestWrapper = new BodyReaderHttpServletRequestWrapper(  
                    (HttpServletRequest) request);  
        }  
    }  

    if (requestWrapper == null) {  
        chain.doFilter(request, response);  
    } else {  
        chain.doFilter(requestWrapper, response);   
    }  
}  

@Override  
public void init(FilterConfig arg0) throws ServletException {  

}  

}

在web.xml 配置

[html] view plain copy 在CODE上查看代码片派生到我的代码片


HttpServletRequestReplacedFilter

com.microdata.core.filter.HttpServletRequestReplacedFilter



encoding

utf-8







HttpServletRequestReplacedFilter

/*

Encodes 类
[html] view plain copy 在CODE上查看代码片派生到我的代码片
package com.microdata.core.util;

import java.io.UnsupportedEncodingException;

import java.net.URLDecoder;

import java.net.URLEncoder;

import org.apache.commons.codec.DecoderException;

import org.apache.commons.codec.binary.Base64;

import org.apache.commons.codec.binary.Hex;

import org.apache.commons.lang3.StringEscapeUtils;

/**

  • 封装各种格式的编码解码工具类.

  • 1.Commons-Codec的 hex/base64 编码
  • 2.自制的base62 编码
  • 3.Commons-Lang的xml/html escape
  • 4.JDK提供的URLEncoder
  • */

    public class Encodes {

    private static final String DEFAULT_URL_ENCODING = "UTF-8";

    private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

    /**

    • Hex编码.
      */
      public static String encodeHex(byte[] input) {
      return Hex.encodeHexString(input);
      }

    /**

    • Hex解码.
      */
      public static byte[] decodeHex(String input) {
      try {
      return Hex.decodeHex(input.toCharArray());
      } catch (DecoderException e) {
      throw Exceptions.unchecked(e);
      }
      }

    /**

    • Base64编码.
      */
      public static String encodeBase64(byte[] input) {
      return Base64.encodeBase64String(input);
      }

    /**

    • Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
      */
      public static String encodeUrlSafeBase64(byte[] input) {
      return Base64.encodeBase64URLSafeString(input);
      }

    /**

    • Base64解码.
      */
      public static byte[] decodeBase64(String input) {
      return Base64.decodeBase64(input);
      }

    /**

    • Base62编码。
      */
      public static String encodeBase62(byte[] input) {
      char[] chars = new char[input.length];
      for (int i = 0; i < input.length; i++) {
      chars[i] = BASE62[(input[i] & 0xFF) % BASE62.length];
      }
      return new String(chars);
      }

    /**

    • Html 转码.
      */
      public static String escapeHtml(String html) {
      return StringEscapeUtils.escapeHtml4(html);
      }

    /**

    • Html 解码.
      */
      public static String unescapeHtml(String htmlEscaped) {
      return StringEscapeUtils.unescapeHtml4(htmlEscaped);
      }

    /**

    • Xml 转码.
      */
      public static String escapeXml(String xml) {
      return StringEscapeUtils.escapeXml(xml);
      }

    /**

    • Xml 解码.
      */
      public static String unescapeXml(String xmlEscaped) {
      return StringEscapeUtils.unescapeXml(xmlEscaped);
      }

    /**

    • URL 编码, Encode默认为UTF-8.
      */
      public static String urlEncode(String part) {
      try {
      return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
      } catch (UnsupportedEncodingException e) {
      throw Exceptions.unchecked(e);
      }
      }

    /**

    • URL 解码, Encode默认为UTF-8.
      */
      public static String urlDecode(String part) {
      try {
      return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
      } catch (UnsupportedEncodingException e) {
      throw Exceptions.unchecked(e);
      }
      }
      }