@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class UrlDecodeFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
ParameterMap<String, String[]> parameterMap = (ParameterMap) httpServletRequest.getParameterMap();
ParamHttpServletRequestWrapper wrapper = new ParamHttpServletRequestWrapper(httpServletRequest, parameterMap);
Enumeration<String> parameterNames = wrapper.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String parameter = httpServletRequest.getParameter(paramName);
if (StringUtils.isNotBlank(parameter)) {
String decode = URLDecoder.decode(parameter, GaeaConstant.CHARSET_UTF8);
parameterMap.setLocked(false);
parameterMap.put(paramName, new String[]{decode});
}
}
filterChain.doFilter(wrapper, servletResponse);
}
/**
* 参数
*/
class ParamHttpServletRequestWrapper extends HttpServletRequestWrapper {
private ParameterMap<String, String[]> parameterMap;
public ParamHttpServletRequestWrapper(HttpServletRequest request, ParameterMap<String, String[]> parameterMap) {
super(request);
this.parameterMap = parameterMap;
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public Enumeration<String> getParameterNames() {
Set<String> keySet = parameterMap.keySet();
IteratorEnumeration iteratorEnumeration = new IteratorEnumeration(keySet.iterator());
return iteratorEnumeration;
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
}
}
这段代码实现了一个 Filter
,用于拦截和处理 HTTP 请求中的参数,并对这些参数进行 URL 解码操作。以下是对这段代码的详细解释:
主要功能
-
类声明
@Component
: 标记该类为一个 Spring 组件,会被 Spring 自动扫描和注册到容器中。@Order(Ordered.HIGHEST_PRECEDENCE + 1)
: 设定过滤器的执行顺序,优先级非常高,仅次于最高优先级。- 这个类实现了
Filter
接口,用来拦截 HTTP 请求,并可以在请求进入目标资源前进行预处理。
-
doFilter
方法doFilter
方法是Filter
接口中的核心方法,它在每个请求到达目标资源之前执行。- 这里首先将
ServletRequest
转换为HttpServletRequest
,以便处理 HTTP 请求的参数。 - 使用
ParameterMap
存储请求参数的映射关系,并创建了一个自定义的ParamHttpServletRequestWrapper
来包装HttpServletRequest
。
-
参数解码逻辑
- 遍历请求中的所有参数 (
parameterNames
),并通过httpServletRequest.getParameter(paramName)
获取参数值。 - 如果参数不为空 (
StringUtils.isNotBlank(parameter)
),则使用URLDecoder.decode
方法对参数进行 URL 解码,假设编码格式为UTF-8
。 - 将解码后的参数重新放入
parameterMap
,并确保parameterMap
在操作时不被锁定 (parameterMap.setLocked(false)
),以允许修改。
- 遍历请求中的所有参数 (
-
传递包装后的请求
- 最后,调用
filterChain.doFilter(wrapper, servletResponse)
,将包装后的请求继续传递给下一个过滤器或最终的目标资源。
- 最后,调用
内部类 ParamHttpServletRequestWrapper
该类继承自 HttpServletRequestWrapper
,用于重写 HttpServletRequest
的参数处理方法,以实现对解码后的参数进行控制。
getParameterMap
:返回修改后的parameterMap
。getParameterNames
:返回一个包含参数名的枚举类,使用了自定义的IteratorEnumeration
来遍历参数名集合。getParameterValues
:返回对应参数名的值数组。
总结
这个过滤器的作用是在 HTTP 请求中,对所有参数进行 URL 解码,并用解码后的值替换原始参数,从而确保在后续处理过程中,所有参数都是解码后的值。