关于 preHandle 重写和添加参数问题,重写HttpServletRequestWrapper和Filter

时间:2024-06-21 17:36:56

由于 preHandle 中HttpServletRequest 只有setAttribute而没有setParameter 也没有 add 方法

所以是没办法直接添加参数的。从网上查了很多资料,基本都是说要重写HttpServletRequestWrapper

说干就干,通过网上查博客看看别人的实现方式,可能因为自己底子不够扎实吧,很多都看不懂,摸索了

一天总算是弄出来了。现在记录一下,方便以后查阅。

首先,创建一个ChangeRequestWrapper 类继承HttpServletRequestWrapper,代码如下

package com.ccs.ssmis.common.interceptors;

import com.ccs.ssmis.common.redis.RedisUtils;
import com.ccs.ssmis.common.utils.Constants; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*; public class ChangeRequestWrapper extends HttpServletRequestWrapper { private Map<String, String[]> parameterMap; // 所有参数的Map集合 public ChangeRequestWrapper(HttpServletRequest request) {
super(request);
parameterMap = request.getParameterMap();
} /**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();
} /**
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
*
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
String[] results = parameterMap.get(name);
return results[0];
} /**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据
* 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
} @Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
  
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
} }

接着重写Filter。代码如下

package com.ccs.ssmis.common.interceptors;

import com.ccs.ssmis.common.redis.RedisUtils;
import com.ccs.ssmis.common.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; public class LangFilter implements Filter { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ChangeRequestWrapper changeRequestWrapper = new ChangeRequestWrapper((HttpServletRequest) servletRequest); Map<String, String[]> parameterMap = new HashMap<>(changeRequestWrapper.getParameterMap()); String[] strings = parameterMap.get("token");
//逻辑代码 判断有没有传入token,如果没有,则直接通过
if (strings == null || strings.length == 0) {
changeRequestWrapper.setParameterMap(parameterMap);
}else{
logger.info("=============拦截器解析token==================");
parameterMap.put("token", strings);
//解析token
Map<String, Object> map = RedisUtils.getMap(strings[0] + Constants.token_Suffix);
parameterMap.put("isok", "false".split(","));
if (map!=null) {
parameterMap.put("userId", map.get("userId").toString().split(","));
parameterMap.put("isok", "true".split(","));
}
changeRequestWrapper.setParameterMap(parameterMap);
}
//复写 HttpServletRequestWrapper
filterChain.doFilter(changeRequestWrapper, servletResponse);
} @Override
public void destroy() { } }

接着 在web.xml 新增拦截器配置,直接复制进去就可以了。

  <filter>
<filter-name>languageFilter</filter-name>
<filter-class>com.ccs.ssmis.common.interceptors.LangFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>languageFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

注意:配置的拦截器会在preHandle方法之前执行。所以逻辑代码可以直接写在Filter的重写类里面

希望大家共同学习共同进步。谢谢。

本博客是借鉴别人的博客改写的,转载请注明来处谢谢。

参考地址:https://www.cnblogs.com/cach/p/8052108.html

链接地址:http://www.cnblogs.com/richard-ju/p/L2018003.html