掰po 2016-08-07 19:57 采纳率: 0%
浏览 4981
已结题

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

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

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

  • 写回答

1条回答 默认 最新

  • devmiao 2016-08-08 00:12
    关注

    一般我们会在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);
        }
        }
        }
    评论

报告相同问题?

悬赏问题

  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂