在springBoot项目内自写的一个过滤器(对请求响应信息做加解密处理,见案例)

过滤器使用案例:
package Filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: lvyk
 * @Description: 过滤器
 * @Date: 2020/5/26 16:29
 */
@Component//http://10.7.213.151:9007/test/api/v1/mytest
@WebFilter(filterName = "myFilter",urlPatterns = "/api/v1/*",/*通配符(*)表示对所有的web资源进行拦截*/
        initParams = {@WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/})
@Slf4j
public class MyFilter implements Filter {

    private String filterName;

    @Autowired
    private FilterUtil filterUtil;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        filterName = filterConfig.getFilterName();
        log.info("过滤器初始化方法,过滤器名:"+filterName);
        //初始化方法

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
        //过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理
        log.info(filterName+":执行过滤方法开始====");

        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        HttpServletRequest httpServletRequest = (HttpServletRequest) req;
        //获取请求报文
        String requestBody = filterUtil.getRequestBody(httpServletRequest);
        //对请求报文做解密处理
        String decryptBASE64="";
        try {
            decryptBASE64 = new String(filterUtil.decryptBASE64(requestBody));
            log.info("解密请求报文:"+decryptBASE64);
        } catch (Exception e) {
            log.info("请求报文解密失败。");
            e.printStackTrace();
        }

        Map<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("content-type","application/json");

        RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest, decryptBASE64);
        String headerNames = requestWrapper.getHeader("content-type");
        String httpServletRequestHeader = httpServletRequest.getHeader("content-type");
        //设置请求头
        requestWrapper.addHeader("content-type","application/json");
        headerNames = requestWrapper.getHeader("content-type");
        httpServletRequestHeader = httpServletRequest.getHeader("content-type");

        //响应处理  包装响应对象 res 并缓存响应数据
        ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) res);
        //demo:对加密报文进行加密
        /*String strDemo="加密测试";
        try {
            log.info("base64加密之前:"+strDemo);
            String encryptBASE64 = encryptBASE64(strDemo.getBytes());
            log.info("base64加密之后:"+encryptBASE64);
            //将加密报文进行解密
            String decryptBASE64 = new String(decryptBASE64(encryptBASE64));
            log.info("base64解密之后:"+decryptBASE64);
        } catch (Exception e) {
            log.info("base64加解密失败");
            e.printStackTrace();
        }*/





        //执行业务逻辑 交给下一个过滤器或servlet处理
        filterChain.doFilter(requestWrapper, responseWrapper);



        byte[] resData = responseWrapper.getResponseData();
        //设置响应内容格式,防止解析响应内容时出错
        responseWrapper.setContentType("text/plain;charset=UTF-8");
        log.info("原始响应报文:\n"+ new String(resData));
        //加密响应报文并响应
        String encryptBASE64="";
        try {
            encryptBASE64 = filterUtil.encryptBASE64(resData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("响应加密报文:"+encryptBASE64);
        filterUtil.writeResponse(res, encryptBASE64);
        log.info(filterName+":执行过滤方法结束====");
    }

    @Override
    public void destroy() {
        //销毁时调用
        log.info(filterName+":服务停止之后过滤器销毁了");

    }


}
请求包装类(由于拿到请求内容进行处理之后发现请求内容丢失了,所以这里进行包装处理):
package Filter;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @Author: lvyk
 * @Description: 请求包装类
 * @Date: 2020/5/26 16:29
 */
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {

    private String requestBody = null;
    //请求体
    private HttpServletRequest req = null;
    //    private final byte[] body;//保存流的字节数组
    private final Map<String, String> reqHeaders=new HashMap<>();


    public RequestWrapper(HttpServletRequest request) throws IOException {

        super(request);
        this.req = request;
//        this.reqHeaders = new HashMap<String, String>();
//        String sessionStream = getRequestBodyStr(request);//读取流中的参数
//        body = sessionStream.getBytes(Charset.forName("UTF-8"));
    }

    public RequestWrapper(HttpServletRequest request, String requestBody) {
        super(request);
        this.requestBody = requestBody;
        this.req = request;
//        this.reqHeaders = request.get;
    }

    /**
     * @Author: lvyk
     * @Description: 获取请求body
     * @Date: 2020/5/26 10:31
     * @Param: [request]
     * @Return: java.lang.String
     */
    public String getRequestBodyStr(final ServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (reader != null) {
                reader.close();
            }
        }
        return sb.toString();
    }

    /**
     * @Author: lvyk
     * @Description: 复制输入流
     * @Date: 2020/5/26 10:33
     * @Param: [inputStream]
     * @Return: java.io.InputStream
     */
    public InputStream cloneInputStream(ServletInputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) > -1) {
            byteArrayOutputStream.write(buffer, 0, len);
        }
        byteArrayOutputStream.flush();
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(req.getCharacterEncoding()));

        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }


    /**
     * 添加header的名称和值
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        reqHeaders.put(name, value);
    }

    @Override
    public String getHeader(String name) {
//        log.info("getHeader --->{}", name);
        String headerValue = super.getHeader(name);
        if (reqHeaders.containsKey(name)) {
            headerValue = reqHeaders.get(name);
        }
        return headerValue;
    }

    /**
     * 得到headers的名称
     */
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : reqHeaders.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
//        log.info("getHeaders name --->>>>>>{}", name);
        List<String> values = Collections.list(super.getHeaders(name));
//        log.info("getHeaders value --->>>>>>{}", values);
        if (reqHeaders.containsKey(name)) {
            log.info("getHeaders --->{}", reqHeaders.get(name));
            values = Arrays.asList(reqHeaders.get(name));
        }
        return Collections.enumeration(values);
    }
}
响应包装类:
package Filter;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

/**
 * @Author: lvyk
 * @Description: 响应包装类
 * @Date: 2020/5/26 16:29
 */
public class ResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream buffer = null;
    private ServletOutputStream out = null;
    private PrintWriter writer = null;

    public ResponseWrapper(HttpServletResponse response) throws IOException {
        super(response);
        buffer = new ByteArrayOutputStream();// 真正存储数据的流
        out = new 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();
    }

    /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
    public byte[] getResponseData() throws IOException {
        flushBuffer();
        return 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 void write(byte[] b) throws IOException {
            bos.write(b, 0, b.length);
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setWriteListener(WriteListener writeListener) {

        }
    }


}

公用Util方法:

package Filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Author lvyk
 * @Description: 供过滤器使用的工具类
 * @Date 2020/5/27 14:05
 * @Modify By:
 */
@Component
@Slf4j
public class FilterUtil {

    /**
     * BASE64加密
     */
    public String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
     * BASE64解密
     */
    public byte[] decryptBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
     * @Author: lvyk
     * @Description: 获取请求信息中请求报文
     * @Date: 2020/5/27 14:08
     * @Param: [req]
     * @Return: java.lang.String
     */
    public String getRequestBody(HttpServletRequest req) {
        try {
            BufferedReader reader = req.getReader();
            StringBuffer sb = new StringBuffer();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String json = sb.toString();
            return json;
        } catch (IOException e) {
            log.error("验签时请求体读取失败", e);
        }
        return "";
    }

    /**
     * @Author: lvyk
     * @Description: 响应内容
     * @Date: 2020/5/27 14:15
     */
    public void writeResponse(ServletResponse response, String responseString) throws IOException {
        PrintWriter out = response.getWriter();
        out.print(responseString);
        out.flush();
        out.close();
    }


}

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值