场景:过滤器中获取参数Token并添加到请求头(用户认证兼容老系统)
请求头和请求参数是不能直接修改,也没有提供修改的方法,但是可以在过滤器和拦截器中使用HttpServletRequestWrapper
包装类达到修改的目的。
一、实现HttpServletRequestWrapper
接口,下面直接使用匿名类
package com.xxxx.web.filter;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.Enumeration;
@WebFilter
public class AuthHeaderSettingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
/**
* 当调用request.getHeader("token")时,则获取请求参数中token值并当做Header的值返回
* @param name
* @return
*/
@Override
public String getHeader(String name) {
// 先从原本的Request中获取头,如果为空且名字为token,则从参数中查找并返回
String superHeader = super.getHeader(name);
if("token".equals(name) && StringUtils.isEmpty(superHeader)){
String token = request.getParameter("token");
if (StringUtils.isNotEmpty(token)) {
return token ;
}
}
return superHeader;
}
};
chain.doFilter(requestWrapper,response);
}
@Override
public void destroy() {
}
}
二、HttpServletRequestWrapper
、ServletRequestWrapper
和HttpServletRequest
接口中的很多方法都可以重写
- 要想增加一个请求参数可以在
HttpServletRequestWrapper
中重写getParameter(String name)
@Override
public String getParameter(String name) {
if("newParam".equals(name)){
return "这是我新增加的参数";
}
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap() {
HashMap<String, String[]> newMap = new HashMap<>();
newMap.putAll(super.getParameterMap());
newMap.put("newParam",new String[]{"这是我新增加的参数"}) ;
return Collections.unmodifiableMap(newMap);
}
@Override
public String[] getParameterValues(String name) {
if("newParam".equals(name)){
return new String[]{"这是我新增加的参数"};
}
return super.getParameterValues(name);
}
注意:
getParameterMap()
返回的时一个不可修改的map ,不能直接向里面put值, 所以在重写这个方法时要自己new 一个HashMap ,然后在新建的map中放值,最后返回时必须调用Collections.unmodifiableMap(Map<? extends K, ? extends V> m)
把map改成不可变的
-
结构
参考:
- Safely add / modify Servlet request parameter values -- 可能要代理才能访问