以前公司作了一個項目,須要與app對接。由於作的是通用服務,app那邊是須要直接訪問的,這樣每次請求兩邊都須要一個憑證來完成一個互相認證的過程。說一下咱們項目採用的方式吧,app那邊將請求參數進行必定規則的加密,生成一個sign值,與參數一塊兒傳遞過來,而後後端在攔截器中一樣將參數按一樣的規則加密,對比sign值是否一致,一致則經過,同理,app那邊也是這樣的認證過程。討論好方案以後天然就是開始寫代碼了。後端
首先天然想到的是經過攔截器藍完成認證的過程。可是在測試過程當中發現,攔截器都返回true了,卻到不了controller層。代碼配置什麼的都沒問題,上網查資料才發現app
request.getInputStream(); request.getReader(); request.getParameter();這些方法都只能被執行一次,再次執行就無效了。思路就是新建一個類A繼承HttpServletRequestWrapper並重寫getInputStream()方法,而後新建一個過濾器,將servletRequest替換成咱們新建的類A。主要代碼以下:ide
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { private final String body; public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; try { InputStream inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[128]; int bytesRead = -1; while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { stringBuilder.append(charBuffer, 0, bytesRead); } } else { stringBuilder.append(""); } } catch (IOException ex) { throw ex; } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ex) { throw ex; } } } body = stringBuilder.toString(); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); ServletInputStream servletInputStream = new ServletInputStream() { public int read() throws IOException { return byteArrayInputStream.read(); } }; return servletInputStream; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(this.getInputStream())); } public String getBody() { return this.body; } }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest requestWrapper = null; if (request instanceof HttpServletRequest) { requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request); } if (null == requestWrapper) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } }