SpringCloud(7)—— 国寿i动项目经验之(过滤器Filter技术(请求体二次解密处理技术))

过滤器Filter技术(请求体二次解密处理技术):

  对前端App请求进行过滤,在过滤中可以对前端请求体(body)进行二次处理,比如:前端请求的body为加密串、那么就可以在过滤器中对body加密串进行二次解密处理,再进行请求具体接口,处理逻辑如下:

 

  过滤器 MyFilter.java

package com.sinosoft.config;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;


/**
 * 使用注解标注过滤器
 *
 * @author 单红宇(365384722)
 * @WebFilter将一个实现了javax.servlet.Filter接口的类定义为过滤器 属性filterName声明过滤器的名称, 可选
 * 属性urlPatterns指定要过滤 的URL模式,也可使用属性value来声明.(指定要过滤的URL模式是必选属性)
 * @myblog http://blog.csdn.net/catoop/
 * @create 2016年1月6日
 */
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(LogRecordAspect.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
        String body = HttpHelper.getBodyString(requestWrapper);
        //如果请求Body为空异常处理
        if (StringUtils.isBlank(body)) {
//            LOGGER.error("非法请求, 没有APP_KEY, APP_SECRET");
            chain.doFilter(request, response);
            return;
        }
        //开始处理请求体
        try {
            LOGGER.info("request:" + body);
            Map<String, Object> parameters = new ObjectMapper().readValue(body.replaceAll("&quot;", "\""), new TypeReference<Map<String, Object>>() {
            });
            Object imReqeustEntityo = parameters.get("imReqeustEntity");
            if (imReqeustEntityo == null || "".equals(imReqeustEntityo)) {
                LOGGER.error("非法请求, 没有设备信息");
            } else {
                Map<String, String> imReqeustEntity = (Map<String, String>) imReqeustEntityo;
                if (imReqeustEntity == null || "".equals(imReqeustEntity)) {
                    LOGGER.error("非法请求, 没有设备信息");
                }
                LOGGER.info("设备信息为: " + imReqeustEntity.toString());
            }
            chain.doFilter(requestWrapper, response);
        } catch (Exception e) {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }

}
BodyReaderHttpServletRequestWrapper.java
package com.sinosoft.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * 使用HttpServletRequestWrapper来包装HttpServletRequest
 * 在BodyReaderHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request
 */
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

    /**
     * 日志打印
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(BodyReaderHttpServletRequestWrapper.class);

    /**
     * 原加密请求体
     */
    private final byte[] body;

    /**
     * 后解密请求体
     */
    private final byte[] resetBody;

    /**
     * 处理request中的请求
     *
     * @param request
     * @throws IOException
     */
    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        String rBody = HttpHelper.getBodyString(request);
        body = rBody.getBytes(Charset.forName("UTF-8"));
        //判断请求体是否为空
//        if (!CommonUtil.isEmpty(rBody)) {
//            LOGGER.info("开始进行AES解密处理...");
//            String aesBody = new String(body, "utf-8");
//            LOGGER.info("请求加密报文:" + aesBody);
//            AES2 aes = new AES2();
//            aesBody = aes.decrypt(aesBody);
//            resetBody = aesBody.getBytes();
//        } else {
//            resetBody = body;
//        }
        resetBody = body;
    }

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

    /**
     * 重置request中的inputStream
     *
     * @return i
     * @throws IOException ioe
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(resetBody);

        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 readListener) {

            }
        };
    }
}
HttpHelper.java
package com.sinosoft.config;

import javax.servlet.ServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * Created with antnest-platform
 * User: chenyuan
 * Date: 12/24/14
 * Time: 10:39 AM
 */
public class HttpHelper {

    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = 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) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

}

 

  

posted @ 2017-06-10 18:52  xu_shuyi  阅读(226)  评论(0)    收藏  举报