通过filter过滤器对请求参数进行处理

通过filter过滤器对请求参数进行处理
置顶2018年04月24日 17:30:00
阅读数:248
遇见的问题:前台把参数通过报文或者使用表单、ajax提交到后台,如果我们的请求参数是加密的,那么我们在controller里面的每一个方法里都需要进行解密处理。如果方法太多,那就太麻烦了。
解决方案:在请求参数到达controller之前,在filter里面进行解密;这样,通过简单的过滤器处理,把需要处理的请求都在过滤器里进行解密操作,这样就等于实现了自动化处理。
这里我们针对两种不同的请求方式进行讲解:1.普通的表单、ajax请求;2.json格式的报文请求。(三步搞定)
1.普通的表单、ajax请求;
第一步:新建一个类
这个类继承自HttpServletRequestWrapper
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* 重写 HttpServletRequestWrapper
* 处理表单、ajax请求
* @author zhaoheng
*
*/
public class MyHttpServletRequestWrapper1 extends HttpServletRequestWrapper{

 // 用于存储请求参数
 private Map<String , String[]> params = new HashMap<String, String[]>();  
 // 构造方法
 public MyHttpServletRequestWrapper1(HttpServletRequest request) throws IOException {    
     super(request);
     // 把请求参数添加到我们自己的map当中
     this.params.putAll(request.getParameterMap()); 
 }    


 /**
  * 添加参数到map中
  * @param extraParams
  */
 public void setParameters(Map<String, Object> extraParams) {
     for (Map.Entry<String, Object> entry : extraParams.entrySet()) {
         setParameter(entry.getKey(), entry.getValue());
     }
 }

 /**
  * 添加参数到map中
  * @param name 
  * @param value
  */
 public void setParameter(String name, Object value) {
     if (value != null) {
         System.out.println(value);
         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)});
         }
     }
 }

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

 /**
  * 重写getParameterValues方法,从当前类的 map中取值
  * @param name
  * @return
  */
 @Override
 public String[] getParameterValues(String name) {
     return params.get(name);
 }

}

通过建立这个类我们就能完成向request对象添加我们处理之后的参数了。
第二步:通过实现filter接口建一个过滤器
package com.zhh.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.zhh.util.request.MyHttpServletRequestWrapper1;

/**
* 参数处理验过滤器(针对ajax、表单等请求) 1.获取请求参数; 2.对获取到的请求参数进行处理(解密、字符串替、请求参数分类截取等等); 3.把处理后的参数放回到请求列表里面
*
* @author zhaoheng
*
*/
public class ValidatorFilter1 implements Filter {

private static final Logger log = Logger.getLogger(ValidatorFilter1.class);

/**
 * 需要过滤的地址
 */
private static List<String> urlList = Arrays.asList("/pastOrder/filterCsF");

/**
 * 是否不需要过滤
 * 
 * @param requestUrl
 *            请求的url
 * @return
 */
public boolean isPast(String requestUrl) {
    for (String url : urlList) {
        if (requestUrl.equals(url)) {
            return true;
        }
    }

    return false;
}

@Override
public void destroy() {
}

@SuppressWarnings("unchecked")
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    log.info("过滤器2执行开始");
    String url = ((HttpServletRequest) request).getRequestURI().substring(((HttpServletRequest)request).getContextPath().length());

    //通过地址对特定的请求进行处理,如果不需要可以不用,如果不用,就会对使用的请求进行过滤
    if (isPast(url)) {
        MyHttpServletRequestWrapper1 requestWrapper1 = new MyHttpServletRequestWrapper1(
                (HttpServletRequest) request);
        // 1.获取需要处理的参数
        String email = requestWrapper1.getParameter("email");
        // 2.把处理后的参数放回去(这里是大小转小写处理)
        requestWrapper1.setParameter("email", email.toLowerCase());
        // 3.放行,把我们的requestWrapper1放到方法当中
        chain.doFilter(requestWrapper1, response);
    } else {
        chain.doFilter(request, response);
    }
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}

}

第三步:在web.xml文件里面进行简单的配置
把我们的过滤器在该文件中注册


ValidatorFilter1

com.zhh.filter.ValidatorFilter1


ValidatorFilter1
/*

9
controller 接收参数代码:
/**
* 过滤方法测试
*/
@RequestMapping(“/filterCsF2”)
public void filterCs22(String email,String userName){
System.out.println(“处理后的参数:”+userName+” “+email);
}

请求示例代码:




请求demo


username:

email:


age:

    <input type="reset" value="重置"/>&nbsp;&nbsp;
    <input type="button" id ="sub" value="提交">
</form>


("#sub").click(
    function(){
        var userName =
("#sub").click(    function(){        var userName =
("#userName").val(); var email = ("#email").val(); 
            var age =
("#email").val();             var age =
("#age").val(); $.ajax({ type : "POST", url:'http://127.0.0.1:8080/merchant_wap/pastOrder/filterCsF2', dataType : "json", data : { "userName":userName, "age":age, "email":email }, success : function(data) { alert("33"); }, error : function(data) { alert("cccc"+data.email); } }); } );

1

处理结果:
处理后的参数:21088888 zhaoheng@163.com
1
从结果可以看出,我们成功的通过过滤器对请求的email进行大写转小写处理
2.json格式的报文请求;
第一步:新建一个类
这个类继承自HttpServletRequestWrapper
package com.zhh.util.request;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import jodd.io.StreamUtil;

/**
* 重写 HttpServletRequestWrapper
* 处理json报文请求
* @author zhaoheng
*
*/
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{

 private  byte[] body; //用于保存读取body中数据   

 public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {    
     super(request);
     //读取请求的数据保存到本类当中
     body = StreamUtil.readBytes(request.getReader(), "UTF-8");    
 }
 //覆盖(重写)父类的方法
 @Override    
 public BufferedReader getReader() throws IOException {    
     return new BufferedReader(new InputStreamReader(getInputStream()));    
 }    
 //覆盖(重写)父类的方法
 @Override    
 public ServletInputStream getInputStream() throws IOException {    
     final ByteArrayInputStream bais = new ByteArrayInputStream(body);    
     return new ServletInputStream() {    
         @Override    
         public int read() throws IOException {    
             return bais.read();    
         } 
     };    
 }

 /**
  * 获取body中的数据
  * @return
  */
public byte[] getBody() {
    return body;
}
/**
 * 把处理后的参数放到body里面
 * @param body
 */
public void setBody(byte[] body) {
    this.body = body;
}

}

14
通过建立这个类我们就能完成向request对象添加我们处理之后的参数了。
第二步:通过实现filter接口建一个过滤器
package com.zhh.filter;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhh.util.request.MyHttpServletRequestWrapper;

/**
* 参数校验过滤器(针对json报文请求) 1.获取请求参数; 2.对获取到的请求参数进行处理(解密、字符串替、请求参数分类截取等等); 3.把处理后的参数放回到请求列表里面
*
* @author zhaoheng
*
*/
public class ValidatorFilter implements Filter {

private static final Logger log = Logger.getLogger(ValidatorFilter.class);

/**
 * 需要过滤的地址
 */
private static List<String> urlList = Arrays.asList("/pastOrder/filterCs");
/**
 * 是否需要过滤
 * 
 * @param requestUrl
 *            请求的url
 * @return
 */
public boolean isPast(String requestUrl) {
    for (String url : urlList) {
        if (requestUrl.equals(url)) {
            return true;
        }
    }
    return false;
}

@Override
public void destroy() {
    log.info("过滤器执行结束");
}

@SuppressWarnings("unchecked")
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    log.info("过滤器1执行开始");
    String url0 = ((HttpServletRequest) request).getRequestURI();
    String url1 = ((HttpServletRequest) request).getContextPath();
    System.out.println("完整地址:"+url0);
    System.out.println("返回当前页面所在的应用的名字:"+url1);
    System.out.println("返回当前页面所在的应用的名字长度:"+url1.length());

    // 获取请求地址
    String url = ((HttpServletRequest) request).getRequestURI().substring(((HttpServletRequest)request).getContextPath().length());
    System.out.println("截取后的地址:"+url);

    if (isPast(url)) {
        //处理json报文请求
        MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(
                (HttpServletRequest) request);
        // 读取请求内容
        BufferedReader br;
        br = requestWrapper.getReader();
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        // 将json字符串转换为json对象
        JSONObject jsonObject = JSONObject.parseObject(sb.toString());

        Map<String, Object> map = new HashMap<String, Object>();
        // 把json对象转换为Map集合
        map = JSON.toJavaObject(jsonObject, Map.class);
        for (Entry<String, Object> entry : map.entrySet()) {
            // 把邮箱地址转换为小写
            if (entry.getKey().equals("email")) {
                map.put(entry.getKey(), entry.getValue().toString()
                        .toLowerCase());
            }
        }

        // 把参数转换之后放到我们的body里面
        String json = JSON.toJSONString(map);
        requestWrapper.setBody(json.getBytes("UTF-8"));
        // 放行 
        chain.doFilter(requestWrapper, response);
    } else {
        chain.doFilter(request, response);
    }
}

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

}

}

第三步:在web.xml文件里面进行简单的配置
把我们的过滤器在该文件中注册


ValidatorFilter

com.zhh.filter.ValidatorFilter


ValidatorFilter
/*

controller 接收参数代码:
/**
* 过滤方法测试
* @RequestBody User user 该注解用于接收json请求的参数
* @return
*/
@ResponseBody
@RequestMapping(value = “/filterCs”)
public User filterCs(@RequestBody User user){
System.out.println(user.toString());
return user;
}

请求报文示例:
我这里使用的是postman工具进行json参数请求
{
“email”: “zhaoHENG@163.com”,
“userName”:”20181100”,
“age”:”18”
}

返回结果:
{
“email”: “zhaoheng@163.com”,
“userName”:”20181100”,
“age”:”18”
}

通过该过滤器,把email转换从小写成功。
通过以上操作,我们就成功的创建了一个过滤器。

进行 POST 请求时,可以使用 filter 进行拦截和处理。具体步骤如下: 1. 创建一个实现了 javax.servlet.Filter 接口的类,重写其的 doFilter 方法。 2. 在 doFilter 方法,可以通过 request.getParameter 方法获取请求参数,根据参数进行相应的处理,并将处理结果封装成一个新的 request 对象。 3. 最后调用 filterChain.doFilter 方法,将处理后的请求对象和响应对象传递给下一个过滤器或 Servlet 进行处理。 示例代码如下: ```java public class PostFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; if ("POST".equalsIgnoreCase(httpServletRequest.getMethod())) { // 获取请求参数 String param1 = request.getParameter("param1"); String param2 = request.getParameter("param2"); // 进行处理 // ... // 封装处理结果 HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpServletRequest) { @Override public String getParameter(String name) { if ("param1".equalsIgnoreCase(name)) { return "newParam1"; } else if ("param2".equalsIgnoreCase(name)) { return "newParam2"; } return super.getParameter(name); } }; // 调用下一个过滤器或 Servlet 进行处理 filterChain.doFilter(requestWrapper, response); return; } } filterChain.doFilter(request, response); } } ``` 在 web.xml 文件配置 filter: ```xml <filter> <filter-name>PostFilter</filter-name> <filter-class>com.example.PostFilter</filter-class> </filter> <filter-mapping> <filter-name>PostFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 这样,当 POST 请求到达时,就会被 PostFilter 拦截并进行处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值