Springboot 使用過濾器進行加密解密(二)

以前寫過一篇關於過濾器實現加密解密功能的文章,可是在實際開發業務中發現,仍是有一些問題的,在此特意說明。

第一:過濾器走兩遍的問題:

1.過濾器上,添加了兩個註解java

第一個:@Compent   將此Filter交給Spring容器管理app

第二個:@WebFilter經過WebFilter進行Filter聲明,這樣容器在進行部署的時候就會處理該Filteride

2.啓動類上添加的註解this

@ServletComponentScan  做用:Servlet、Filter、Listener 能夠直接經過 @WebServlet、@WebFilter、@WebListener 註解自動註冊(自動掃描帶有過濾器註解的包)加密

3.問題:項目啓動後,一個請求執行兩次url

緣由:@Compent 啓動時,會加載Filter.  @ServletComponentScan 也會掃描過濾器。因此會加載兩次spa

4.解決措施:code

去掉過濾器上的@Compent 註解以後,請求過濾一次。blog

第二:響應結果跟加密結果不一致的問題

1.以前使用的包裝類,不知道爲什麼,加密的結果和最終響應的結果不一致,而且是有規律的少。開發

各位大神,若是知道爲何的話,麻煩指點一下。

 

2.解決辦法:直接換了一個包裝類,代碼以下:

包裝類代碼:

import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; /** * reponse包裝類,對reponse響應進行處理後,傳給客戶端 * @Author: kiki * @Date: 2018/12/18 */ public class WrapperedResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer = null; private ServletOutputStream out = null; private PrintWriter writer = null; public WrapperedResponse(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream();//真正存儲數據的流 out = new WrapperedResponse.WapperedOutputStream(buffer); writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding())); } //重載父類獲取outputstream的方法  @Override public ServletOutputStream getOutputStream() throws IOException { return out; } //重載父類獲取writer的方法  @Override public PrintWriter getWriter() throws UnsupportedEncodingException { return writer; } //重載父類獲取flushBuffer的方法  @Override public void flushBuffer() throws IOException { if (out != null) { out.flush(); } if (writer != null) { writer.flush(); } } @Override public void reset() { buffer.reset(); } public String getContent() throws IOException { flushBuffer();//將out、writer中的數據強制輸出到WapperedResponse的buffer裏面,不然取不到數據 return new String(buffer.toByteArray()); } //內部類,對ServletOutputStream進行包裝 private class WapperedOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos = null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException { bos = stream; } @Override public void write(int b) throws IOException { bos.write(b); } @Override public boolean isReady() { return false; } @Override public void setWriteListener(WriteListener listener) { } } }

 過濾器代碼:

/** * 過濾器攔截請求,實現加密解密功能 * * @Component 將此Filter交給Spring容器管理 * @WebFilter 經過WebFilter進行Filter聲明,這樣容器在進行部署的時候就會處理該Filter * * @author kiki */ @WebFilter(urlPatterns = "/HMService/*", filterName = "dataFilter") public class DataFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub  } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //解密請求 //使用包裝類 對request/response進行修改和響應 WrapperedRequest wrapRequest = new WrapperedRequest((HttpServletRequest) request, requestBodyMw); WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse) response); chain.doFilter(wrapRequest, wrapResponse); String content = wrapResponse.getContent(); String responseBodyMw = DES3Util.encodeCBC(content); logger.info("【加密返回數據爲】 responseBodyMw = {}", responseBodyMw); response.setContentLength(-1); PrintWriter out = response.getWriter(); System.out.println(responseString.length()); out.write(responseBodyMw); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public void destroy() { // TODO Auto-generated method stub  } }

 

修改以後,加密的結果和響應的結果一致。

 

說明:這是個大坑呀,剛開始沒有發現這個問題,返回的是加密的字符串就認爲是對的,可是客戶端就是解析不了。我才知道,加密的結果和最終響應的結果不同,特此記錄。

相關文章
相關標籤/搜索