想要回去GET请求中的请求参数,能够直接使用request.getParamMap()方法。可是POST请求的requestBody参数就必须使用流的方式来获取。java
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("流读取错误:"+e); return; }finally { if (null != reader){ try { reader.close(); } catch (IOException e) { logger.error("流关闭错误:"+e); } } } Map<String,Object> paramMap = JSON.parseObject(body);
这样将获取body中的全部json格式的参数信息。能够根据需求,进行验签或校验等一系列操做。可是当咱们chain.doFilter(request, response),惊喜的发现接口400了!!
WHAT??!!
嘿嘿o( ̄▽ ̄)d
咱们都知道,读取流的时候是有标志的,读取一次移动一次,读取到哪里,移动到哪里,读到最后,返回-1,表示读取完成。再次读取须要重置位置,可是ServletInputStream中是没有重置方法的,也就是说流只能被读取一次。神奇!!Σ(⊙▽⊙"a 此时的流已经被读取一次,至关于已经做废,此时请求接口必然是报错的。
行吧,你既然不让我重复读,那我就把你的流拿过来封装成本身的流,这样我想读多少次就读多少次!ψ(`∇´)ψ
加入jar包:javax.servletjson
<!-- 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>
实现HttpServletRequestWrapper类api
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) {// 重写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; } }
解码app
/** * URL 解码, Encode默认为UTF-8. */ public static String urlDecode(String part) { try { return URLDecoder.decode(part, DEFAULT_URL_ENCODING); } catch (UnsupportedEncodingException e) { throw new InvalidTokenException(part); } }
那么上面读取参数的代码修改成:ide
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("流读取错误:"+e); return; }finally { if (null != reader){ try { reader.close(); } catch (IOException e) { logger.error("流关闭错误:"+e); } } } Map<String,Object> paramMap = JSON.parseObject(body); . . . chain.doFilter(requestWrapper, response);
OK!又是打酱油的一天。(づ。◕ᴗᴗ◕。)づ函数