利用过滤器对请求的接口数据进行自定义操作

过滤器中对请求参数的操作

在工作中经常会有遇到Fitler过滤器的操作,这里就不介绍了,主要说明在过滤器中如何对强求的参数进行获取、操作、最后返回给controller

案例:

在一些app中,为了保护我们的请求安全,我们会对接口的参数,进行加密处理,之后再后端进行解密,在进行强求,但是我们不能每一个接口都去写一个解密方法或者调用解密方法,所有我们可以用aop或者Fitler进行操作,统一处理,这里只说Fitler过滤器

1、自定义一个request类

package com.cesec.utils.encrypt;

import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class WrapperedRequest extends HttpServletRequestWrapper {

    private HttpServletRequest req = null;
    private Map<String , String[]> params = new HashMap<String, String[]>();
    //用于POST请求
    private String body = null;

    public WrapperedRequest(HttpServletRequest request) {
        // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
        super(request);
        this.req = request;
        //将参数表,赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
    }

    //重载一个构造方法
    public WrapperedRequest(HttpServletRequest request , Map<String, String> extendParams) {
        this(request);
        addAllParameters(extendParams);//这里将扩展参数写入参数表
    }

    public WrapperedRequest(HttpServletRequest request, String body) {
        super(request);
        this.body=body;
    }

    @Override
    public String getParameter(String name) {//重写getParameter,代表参数从当前类中的map获取
        String[]values = params.get(name);
        if(values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return params;
    }

    public String[] getParameterValues(String name) {//同上
        return params.get(name);
    }

    public void addAllParameters(Map<String , String>otherParams) {//增加多个参数
        for(Map.Entry<String , String>entry : otherParams.entrySet()) {
            addParameter(entry.getKey() , entry.getValue());
        }
    }

    public void addParameter(String name , Object value) {//增加参数
        if(value != null) {
            if(value instanceof String[]) {
                params.put(name , (String[])value);
            }else if(value instanceof String) {
                params.put(name , new String[] {(String)value});
            }else {
                params.put(name , new String[] {String.valueOf(value)});
            }
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        ServletInputStream inputStream = null;
        if(StringUtils.isNotEmpty(body)){
            inputStream =  new PostServletInputStream(body);
        }
        return inputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        String enc = getCharacterEncoding();
        if(enc == null) enc = "UTF-8";
        return new BufferedReader(new InputStreamReader(getInputStream(), enc));
    }

}

2、自定义一个Response

package com.cesec.utils.encrypt;

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

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 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);
        }
    }
}

3、相关工具类方法

// 解析请求参数为map
    private HashMap<String, String> getParams(HttpServletRequest request) {
        /
        HashMap<String, String> hmParams = getRequestParams(request);
        Gson gson = new Gson();
        if (hmParams == null || hmParams.size() == 0) {
            byte[] bytes = null;
            try {
                bytes = getDataFromStream(request.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
                bytes = null;
            }
            if (bytes != null && bytes.length > 0) {
                hmParams = new HashMap<String, String>();
                String temp = new String(bytes);
                if (temp.startsWith("{") || temp.startsWith("[")) {
                    hmParams = new Gson().fromJson(temp, new TypeToken<HashMap<String, String>>() {
                    }.getType());
                }
            }

        }
		(这个是我自己的相关解密方法,可根据自己业务调整)
        /**String params = hmParams.get(ParamKeyEnum.params.name());
        if (params != null && params.length() > 0) {
            try {
                params = DesUtils.decrypt(params);
            } catch (Exception e) {
                logger.errorWithNoTrans("解密params数据发生错误!", logger, e);
                return null;
            }
            logger.debug("解密后的params数据为:" + params, logger);
         */
            // 解析参数为HashMap
            if (params.startsWith("{") || params.startsWith("[")) {
                hmParams = new Gson().fromJson(params, new TypeToken<HashMap<String, String>>() {
                }.getType());
                hmParams.remove(ParamKeyEnum.params.name());
                hmParams.put(ParamKeyEnum.params.name(), params);
            }
        }

        return hmParams;
    }
//获取get请求中的数据
public HashMap<String, String> getRequestParams(HttpServletRequest request) {
		HashMap<String, String> hmParams = new HashMap<String, String>();
		try {
			String encoding = request.getCharacterEncoding();
			// tomcat需要配置编码为utf-8
			encoding = encoding == null || "".equals(encoding) ? "UTF-8" : encoding;
			Enumeration<String> parameterNames = request.getParameterNames();
			while (parameterNames.hasMoreElements()) {
				String paramName = parameterNames.nextElement();
				String value = request.getParameter(paramName);
				hmParams.put(paramName, new String(value.getBytes(encoding), "UTF-8"));
			}
		} catch(Exception e) {
			LogUtils.errorWithNoTrans("[getParams][HttpServletRequest]解析请求参数出错",logger,e);
		}
		return hmParams;
	}
//获取body中的数据(post请求的数据)	
public static byte[] getDataFromStream(InputStream input) {
		DataInputStream dataInputStream = null;
		ByteArrayOutputStream byteStream = null;

		try {
			dataInputStream = new DataInputStream(input);
			byteStream = new ByteArrayOutputStream();
			byte bufferByte[] = new byte[1024 * 8];

			for (int l = -1; (l = dataInputStream.read(bufferByte)) > -1;) {
				byteStream.write(bufferByte, 0, l);
				byteStream.flush();
			}

			byte inByte[] = byteStream.toByteArray();
			if (inByte.length == 0) {
				inByte = null;
			}

			return inByte;
		} catch(Exception e) {
			LogUtils.errorWithNoTrans("[getDataFromStream]获取输入流的数据时失败",logger,e);
			return null;
		} finally {
			try {
				if (dataInputStream != null) {
					dataInputStream.close();
					dataInputStream = null;
				}

				if (byteStream != null) {
					byteStream.close();
					byteStream = null;
				}
			} catch (IOException e) {
			}
		}
	}

4、获取参数进行相关操作

public class EncyptFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
		String contentType = request.getContentType();//请求方式
 try {
                // 解析请求参数为map
                WrapperedResponse wrapResponse = new WrapperedResponse(response);//创建自定义的response类
                WrapperedRequest wrapRequest = null; //创建自定义的Request类
                //带有图片的请求
                if (StringUtils.isNotEmpty(contentType) && (contentType.contains("multipart/form-data"))) {
                    MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
                    MultipartHttpServletRequest paramsTest = resolver.resolveMultipart(request);
                    //获取前段请求的数据
                    MultiValueMap<String, MultipartFile> multiFileMap = paramsTest.getMultiFileMap()//获取所有值
                    String params = paramsTest.getParameter("params");//获取key为params的值  与自己业务相关这里是加密参数
                    MultipartFile file = paramsTest.getFile("file");//获取图片信息
              

					//获取request中的值转为map
                    HashMap<String, String> hmParams = getRequestParams(paramsTest);
				// 拿到自己想要的参数,可以做自己想要的操作  
					//列如:对参数进行了解密操作
                    if (hmParams != null) {
                        HttpServletRequest revertServletRequest = (HttpServletRequest) paramsTest;
                        wrapRequest = new WrapperedRequest(revertServletRequest, JSONObject.toJSONString(hmParams));
                        wrapRequest.addAllParameters(hmParams);
                        for (Map.Entry<String, List<MultipartFile>> entry : multiFileMap.entrySet()) {
                            wrapRequest.addParameter(entry.getKey(), entry.getValue());
                        }
                        filterChain.doFilter(wrapRequest, wrapResponse);
                    }
                } else if (StringUtils.isNotEmpty(contentType) && contentType.contains("application/json")) {
                    Map<String, String> params = getParams(request);
                    if (!ObjectUtils.isEmpty(params )) {
                        wrapRequest = new WrapperedRequest(request, JSONObject.toJSONString(params));
                        filterChain.doFilter(wrapRequest, wrapResponse);
                    } else {
                        LogUtils.errorWithNoTrans("非法请求", logger, new Exception("非法请求"));
                        response.getWriter().close();
                        return;
                    }
                } else {
                    Map<String, String> params = getParams(request, dto);
                    wrapRequest = new WrapperedRequest(request, params);
                    filterChain.doFilter(wrapRequest, wrapResponse);
                }
            } catch (Exception e) {
                LogUtils.errorWithNoTrans("请求加密处理异常,e=" + e.getLocalizedMessage(), logger, e);
            }
    }

    @Override
    public void destroy() {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值