之前写过一篇关于过滤器实现加密解密功能的文章,但是在实际开发业务中发现,还是有一些问题的,在此特地说明。
第一:过滤器走两遍的问题:
1.过滤器上,添加了两个注解
第一个:@Compent 将此Filter交给Spring容器管理
第二个:@WebFilter通过WebFilter进行Filter声明,这样容器在进行部署的时候就会处理该Filter
2.启动类上添加的注解
@ServletComponentScan 作用:Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册(自动扫描带有过滤器注解的包)
3.问题:项目启动后,一个请求执行两次
原因:@Compent 启动时,会加载Filter. @ServletComponentScan 也会扫描过滤器。所以会加载两次
4.解决措施:
去掉过滤器上的@Compent 注解之后,请求过滤一次。
第二:响应结果跟加密结果不一致的问题
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 } }
修改之后,加密的结果和响应的结果一致。
说明:这是个大坑呀,刚开始没有发现这个问题,返回的是加密的字符串就认为是对的,但是客户端就是解析不了。我才知道,加密的结果和最终响应的结果不一样,特此记录。
原文地址:https://www.cnblogs.com/kaile/p/10195388.html
时间: 2025-01-30 05:53:49