本文章参考了网上一些代码,经本人实验没有问题
request处于安全考虑是不能直接修改的,所以要自定义一个request继承他的类。下面是代码
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyRequest extends HttpServletRequestWrapper {
private Map<String , String[]> params = new HashMap<String, String[]>();
@SuppressWarnings("unchecked")
public MyRequest(HttpServletRequest request) {
// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
super(request);
//将参数表,赋予给当前的Map以便于持有request中的参数
this.params.putAll(request.getParameterMap());
}
//重载一个构造方法
public MyRequest(HttpServletRequest request , Map<String , Object> extendParams) {
this(request);
addAllParameters(extendParams);//这里将扩展参数写入参数表
}
public Map<String , String[]> getParameterMap() {
return params;
}
public Enumeration getParameterNames() {
Vector l = new Vector(params.keySet());
return l.elements();
}
@Override
public String getParameter(String name) {//重写getParameter,代表参数从当前类中的map获取
String[]values = params.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
public String[] getParameterValues(String name) {//同上
return params.get(name);
}
public void addAllParameters(Map<String , Object>otherParams) {//增加多个参数
for(Map.Entry<String , Object>entry : otherParams.entrySet()) {
addParameter(entry.getKey() , entry.getValue());
}
}
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)});
}
}
}
public void removeParameter(String name) {
if(params.get(name)!=null) {
params.remove(name);
}
}
}
这个时候我们重写了request,关键在于要让action的request变成自定义的action.有两个常用的方法:
1.拦截器
<interceptors>
<interceptor name="hh" class="handChangeInterceptor">
<param name="includeMethods">modifyCarrierDo</param>
</interceptor>
<interceptor-stack name="xxx">
<interceptor-ref name="default"></interceptor-ref>
<interceptor-ref name="hh"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="" class="" method="">
<interceptor-ref name="xxx"></interceptor-ref>
</action>
注意自定义的拦截器要放在默认拦截器后面,因为默认拦截器完成了request,respose,parameter,actioncontext,valuestack等很多东西的数据绑定。
interceptor代码
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import net.sf.json.JSONArray;
@Component
public class HandChangeInterceptor extends ManagementAction<DeliveryOutbound> implements Interceptor{
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation arg0) throws Exception {
System.out.println("拦截器,启动!");
HttpServletRequest request =
(HttpServletRequest) arg0.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
......
......
......
MyRequest requestWrapper = new MyRequest((HttpServletRequest)request);
requestWrapper.addParameter("xxx" , xxx);
ServletActionContext.setRequest(requestWrapper);
ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, requestWrapper);
arg0.getInvocationContext().put(ServletActionContext.HTTP_REQUEST, requestWrapper);
return arg0.invoke();
}
}
可以看到有很多修改request,具体是用哪一个,取决于action里面是怎么拿到request的。然后用自定义的request替换掉原有的request,这样传给action就是你自己的request了,注意了注意了,如果你的项目比较怪异,比如action不是通过任何任何一种方法获取request,那拦截器可能就不行了。过滤器就是最好的选择
2.过滤器
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import net.sf.json.JSONArray;
@Component
public class MyFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("过滤器,启动!");
......
......
......
MyRequest requestWrapper = new MyRequest((HttpServletRequest)request);
requestWrapper.addParameter("xxx" , xxx);
chain.doFilter(requestWrapper, response);
//不给通过的话就用request转发或重定向,是ajax请求,就是下面:
//PrintWriter out = response.getWriter();
// out.print("xxx");//返回一个标识给前端
// out.flush();
// out.close();
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml
<filter>
<filter-name>myfilter</filter-name>
<filter-class>
xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx
</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/xxx/xxx.action</url-pattern>
</filter-mapping>
一般用这个不会出现问题,因为这个是request的根源