Filter向Request中添加参数
1. 情景
系统基于SSM+SpringBoot+JWT。
Token
中通常会带有用户的信息,需要在后端解析出来作为Controller
层的参数,这时就要通过Filter
来处理HttpServletRequest
了。因为HttpServletRequest
是不可改变的,所以要通过HttpServletRequestWrapper
进行包装。采用到了设计模式中的装饰者模式。
2. 代码
import com.dubbo.config.ParameterRequestWrapper;
import com.dubbo.tools.TokenUtils;
import com.dubbo.wrap.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
/**
* @author gyh
* @csdn https://blog.csdn.net/qq_40788718
* @date 2020/4/30 21:39
*/
@WebFilter
@Order(1)
@Component
public class
RequestParameterFilter implements Filter {
@Autowired
@Qualifier(value = "pathSet")
private Set<String> pathSet ;
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest ;
HttpServletResponse response = (HttpServletResponse) servletResponse ;
//跨域
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
ParameterRequestWrapper wrapper = new ParameterRequestWrapper(request) ;
//加入IP参数
wrapper.addParameter("loginIP" , request.getRemoteAddr());
//System.out.println(request.getRemoteAddr());
//包含URL,验证token,成功则加入userId,失败则重定向到登录页
if (pathSet.contains(request.getServletPath())){
String token = request.getParameter("token") ;
User user = null ;
if (token == null || token == "" ||
(user =TokenUtils.isToken(token , request.getRemoteAddr())) == null){
//System.out.println(JacksonUtils.bean2Json(user));
//重定向到登录页
// response.sendRedirect() ;
}else{
//加入UserId参数
wrapper.addParameter("userId" , user.getUserId());
}
}
filterChain.doFilter(wrapper , servletResponse);
}
@Override
public void destroy() {
}
}
需要从token里面获取用户的Id,并且插入到request的参数集合里。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
/**
* @author gyh
* @csdn https://blog.csdn.net/qq_40788718
* @date 2020/4/30 18:40
*/
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String , String[]> params = new HashMap<>() ;
public ParameterRequestWrapper(HttpServletRequest request) {
super(request);
//将参数表,赋予给当前Map以便于持有request中的参数
this.params.putAll(request.getParameterMap());
}
public ParameterRequestWrapper(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){
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 ;
}
/**
* 在获取所有的参数名,必须重写此方法,
* 否则对象中参数值映射不上
* @return
*/
@Override
public Enumeration<String> getParameterNames(){
return new Vector(params.keySet()).elements() ;
}
public void addAllParameters(Map<String, Object> extendParams) {
for (Map.Entry<String , Object> entry : extendParams.entrySet())
addParameter(entry.getKey() , entry.getValue()) ;
}
public void addParameter(String key, Object value) {
if (value != null){
if (value instanceof String[])
params.put(key , (String[])value) ;
else if (value instanceof String)
params.put(key , new String[]{(String) value}) ;
else
params.put(key , new String[]{String.valueOf(value)}) ;
}
}
}
3. HttpServletRequestWrapper
通过类名就可以知道此类是HttpServletRequest
的包装类,通过 this.params.putAll(request.getParameterMap());
将原request中的参数数据转移到当前request(因为我们只添加参数)。
HttpServletRequestWrapper
和 HttpServletResponseWrapper
的作用:
强化和修改
request
和response
4.参考:
https://blog.csdn.net/tyyytcj/article/details/78528499
https://www.cnblogs.com/xuhewei/p/11474389.html
https://www.cnblogs.com/afangfang/p/12812276.html