修改HttpServletRequest中的请求参数

文章目录
  1. 前言
  2. 步骤
    1. 1.实现HttpServletRequestWrapper的子类
    2. 2.实现一个过滤器
    3. *额外说明
      1. 1.在web.xml文件中, 将filter交由spring管理
      2. 2.进行Spring配置文件配置.

前言

有些时候, 我们需要在请求到达Controller之前, 对请求的参数, 即request中的parameter进行修改, 我们发现ServletRequest提供了setAttribute()方法, 然而, 在controller中, 获取request中参数的方法是public String getParameter(String name) 或者 public String[] getParameterValues(String name) 方法.
所以, 这里采用继承javax.servlet.http.HttpServletRequestWrapper装饰者类, 来实现修改request中参数的功能, HttpServletRequestWrapper类是HttpServletRequest接口的实现类, HttpServletRequest接口又是ServletRequest接口的子接口.
其中, HttpServletRequestWrapper对request做一次包装.

步骤

1.实现HttpServletRequestWrapper的子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
public class MyRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<>();
/**
* Constructs a request object wrapping the given request.
*
* @param request
* @throws IllegalArgumentException if the request is null
*/
public MyRequestWrapper(HttpServletRequest request) {
super(request);
//将参数表,赋予给当前的Map以便于持有request中的参数
this.params.putAll(request.getParameterMap());
}
/**
* 重载构造方法
*/
public MyRequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) {
this(request);
//这里将扩展参数写入参数表
addAllParameters(extendParams);
}
/**
* 重写getParameter方法
*
* @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];
}
@Override
public String[] getParameterValues(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values;
}
/**
* 增加多个参数
*
* @param otherParams 增加的多个参数
*/
public void addAllParameters(Map<String, Object> otherParams) {
for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}
/**
* 增加参数
*
* @param name 参数名
* @param value 参数值
*/
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)});
}
}
}
}

2.实现一个过滤器

定义一个请求参数改变的过滤器, 使请求先通过过滤器来修改其中的parameter, 其中, 过滤器filterName通过@WebFilter注解进行定义.
在代码中, 我们使用我们定义的HttpServletRequestWrapper子类MyRequestWrapper来新建一个request, 并对request增加一个参数addParam, 它的值设置为mason字符串. 之后, 再使用chain.doFilter(request, response)让调用链继续执行.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Slf4j
@WebFilter(filterName = "requestParameterFilter")
public class RequestParameterFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
MyRequestWrapper wrapper = new MyRequestWrapper(request);
wrapper.addParameter("addParam", "mason");
chain.doFilter(wrapper, response);
}

完成以上步骤, 我们便实现了对ServletRequest中请求参数的修改.之后在我们的Controller中, 便可以获取到addParam参数, 其值为mason.

*额外说明

由于Filter不是Spring容器中的Bean, 在java开发中, 如果我们希望通过Spring在上述实现的RequestParameterFilter中注入bean, 可以采用如下配置:

1.在web.xml文件中, 将filter交由spring管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--将RequestParameterFilter过滤器交由spring管理-->
<filter>
<filter-name>DelegatingFilterProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>requestParameterFilter</param-value>
</init-param>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DelegatingFilterProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

2.进行Spring配置文件配置.

进行上述配置之后, 在Spring的xml配置文件中, 将我们实现的RequestParameterFilter类配置为bean即可.