本文章介绍关于如何修改Request的请求路径,不是请求转发,也不是重定向。
介绍源码
如果要修改Request的请求路径,就得知道路径是保存在哪个类的哪个字段里面。
跟踪源码可知路径是保存在org.apache.coyote.Request
这个类的uriMB
这个字段里面,uriMB
是一个MessageBytes
类型,MessageBytes
中使用strValue
保存路径,而且在MessageBytes
类中为strValue
提供了setter
,getter
方法,所以你可以调用setter
来改变请求路径。因此Request的路径最终是保存在MessageBytes
的strValue
字段中。
但是光知道路径的保存字段还不够,还得知道在哪里调用。我在这里仅仅说下大概涉及到的类。
org.apache.catalina.connector.RequestFacade;
:
org.apache.catalina.connector.Request
org.apache.coyote.Request
编写代码
import org.apache.catalina.connector.RequestFacade;
import org.apache.coyote.Request;
import org.apache.tomcat.util.buf.MessageBytes;
import javax.servlet.*;
import java.io.IOException;
import java.lang.reflect.Field;
import static javax.swing.UIManager.get;
public class ParseURLFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(servletRequest);
RequestFacade facade= (RequestFacade) servletRequest;
Class clzz=RequestFacade.class;
try {
Field field=clzz.getDeclaredField("request");
field.setAccessible(true);
org.apache.catalina.connector.Request request=(org.apache.catalina.connector.Request) field.get(facade);
Class requestClass=request.getClass();
//获取封装org.apache.coyote.Request的字段
Field coyoteField=requestClass.getDeclaredField("coyoteRequest");
coyoteField.setAccessible(true);
Request coyoteRequest=(Request)coyoteField.get(request);
Class requestClazz=Request.class;
//获取org.apache.coyote.Request中保存路径的字段
Field uriMBField= requestClazz.getDeclaredField("uriMB");
uriMBField.setAccessible(true);
MessageBytes uriMB=(MessageBytes)uriMBField.get(coyoteRequest);
//这里就是改变路径的地方
String path=uriMB.getString()+"dd";
uriMB.setString(path);
filterChain.doFilter(facade,servletResponse);
//用来打印请求路径
System.out.println(((RequestFacade) servletRequest).getRequestURL());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public void destroy() {
}
}