如何使用过滤器或servlet更改请求URL

6
如何使用过滤器或servlet更改requestURL。
例如,如果请求为“http://servername1:8080”,我想将其更改为“http://servername2:7001”。

这种方法行不通。幸运的是,这个方法非常好用:https://dev59.com/TXE85IYBdhLWcg3wikIu - Vladimir Kondratyev
2个回答

19

在您的应用程序中添加以下servlet过滤器:

public class RequestUrlRewritingFilter implements Filter {

    //Empty init()/destroy() here

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequestWrapper wrapped = new HttpServletRequestWrapper(request) {
            @Override
            public StringBuffer getRequestURL() {
                final StringBuffer originalUrl = ((HttpServletRequest) getRequest()).getRequestURL();
                return new StringBuffer("http://servername2:7001");
            }
        };
        chain.doFilter(wrapped, response);
    }
}

你想要拦截的所有请求都必须经过它。正如你所看到的,它接受原始的request方法,并通过返回不同的值来覆盖getRequestURL()方法。如果你想基于旧的URL创建新的URL,仍然可以访问原始请求。

最后,你必须继续处理请求chain.doFilter(),但是要提供包装后的请求,而不是原始请求。


在我的端上,我遇到了这个错误: 构造函数 HttpServletRequestWrapper(ServletRequest) 未定义。 - Rabia Naz khan
Rabia,你可能需要将HttpServletRequest传递给包装器构造函数。 - inor

3

与其他使用 .forward() 的网络解决方案相比,上述解决方案更为优秀,因为它不会破坏过滤器链。该解决方案允许在修改请求后,后续的过滤器继续处理请求。

但是,为了使这个方案对下游过滤器处理透明,必须实现两种附加方法,并且它们必须呈现相同的 URL 修改,以提供一致的请求对象。包装器必须实现:

@Override
public String getRequestURI() {
    final String originalUri = ((HttpServletRequest)getRequest()).getRequestURI();
    return "/"; // Must be consistent with getRequestURL()
}
@Override
public String getServletPath() {
    final String originalPath = ((HttpServletRequest)getRequest()).getServletPath();
    return "/"; // Must be consistent with getRequestURL()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接