java obtains request parameters in POST requests in filter s and resolves the problem of repeated reading of ServletInputStream

Keywords: Java JSON

To go back to the request parameters in the GET request, you can use the request.getParamMap() method directly. However, the requestBody parameter of the POST request must be obtained in a flow manner.

            BufferedReader reader = null;
            String body = null;
            try {
                reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
                body = IOUtils.read(reader).replaceAll("\t|\n|\r", "");
            } catch (IOException e) {
                logger.error("Flow read error:"+e);
                return;
            }finally {
                if (null != reader){
                    try {
                        reader.close();
                    } catch (IOException e) {
                        logger.error("Flow closure error:"+e);
                    }
                }
            }
            Map<String,Object> paramMap = JSON.parseObject(body);

This will get all the json format parameter information in the body. According to the requirements, a series of operations, such as checking or checking, can be carried out. But when we chain.doFilter(request, response), surprise discovery interface 400!!
WHAT??!!
Hey hey o()d
We all know that when reading the stream, there are signs. Read once, move to where, move to where, read to the end, return to - 1, indicating that the reading is complete. Read again requires reset location, but there is no reset method in ServletInputStream, which means that the stream can only be read once. Magical!! (88
Okay, since you won't let me read it again, I'll take your stream and encapsulate it into my own stream, so how many times do I want to read it? _(') _
Join the jar package: javax.servlet

        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

Implementing the HttpServletRequestWrapper class

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.net.URLDecoder;
import java.util.*;

/**
 * @author zhoumin
 * @create 2018-10-31 16:13
 */
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private Map<String, String[]> paramsMap;

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

    @Override
    public String getParameter(String name) {// Override getParameter to get the representative parameter from the map in the current class
        String[] values = paramsMap.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public String[] getParameterValues(String name) {// Ditto
        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;

        // Read data submitted by 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);
    }

    // Custom decoding function
    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 "";// Non-UTF-8 Coding
            }
        }
    }

    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; // message

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

        // First, get data from 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;
    }

}

Decode

/**
     * URL Decode, Encode defaults to UTF-8.
     */
    public static String urlDecode(String part) {
        try {
            return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new InvalidTokenException(part);
        }
    }

Then the code for reading the parameters above is modified to read as follows:

             ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(
                    (HttpServletRequest) request);
            BufferedReader reader = null;
            String body = null;
            try {
                reader = new BufferedReader(new InputStreamReader(requestWrapper.getInputStream()));
                body = IOUtils.read(reader).replaceAll("\t|\n|\r", "");
            } catch (IOException e) {
                logger.error("Flow read error:"+e);
                return;
            }finally {
                if (null != reader){
                    try {
                        reader.close();
                    } catch (IOException e) {
                        logger.error("Flow closure error:"+e);
                    }
                }
            }
            Map<String,Object> paramMap = JSON.parseObject(body);
            .
            .
            .
            chain.doFilter(requestWrapper, response);

OK! Another day of soy sauce. (_)

Posted by DBHostS on Tue, 22 Jan 2019 23:06:13 -0800