HttpServletRequest.getRequestUri不能获取forward之前的uri解决

探讨Servlet中URI转发后如何恢复原始请求URI,介绍Spring UrlPathHelper提供的解决方案,解析getOriginatingRequestUri方法实现。

当调用 RequestDispatcher.forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)后,再调用javax.servlet.ServletRequest的getRequestUr方法得到的是forward后的uri,之前的uri得不到了。servlet规范明确规定了这种情况:getRequestURI

java.lang.String getRequestURI()
Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP request. The web container does not decode this String. For example:
First line of HTTP request	 Returned Value
POST /some/path.html HTTP/1.1		/some/path.html
GET http://foo.bar/a.html HTTP/1.0		/a.html
HEAD /xyz?a=b HTTP/1.1		/xyz
To reconstruct an URL with a scheme and host, use HttpUtils#getRequestURL.

Returns:
a String containing the part of the URL from the protocol name up to the query string
See Also:
HttpUtils#getRequestURL

 getRequestURL

java.lang.StringBuffer getRequestURL()
Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.
If this request has been forwarded using RequestDispatcher.forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse), the server path in the reconstructed URL must reflect the path used to obtain the RequestDispatcher, and not the server path specified by the client.

Because this method returns a StringBuffer, not a string, you can modify the URL easily, for example, to append query parameters.

This method is useful for creating redirect messages and for reporting errors.

Returns:
a StringBuffer object containing the reconstructed URL

 

要想使用forward前的uri就需要费一翻脑筋了,好在spring UrlPathHelper提供了解决方案,public String getOriginatingRequestUri(HttpServletRequest request) 可以获取到之前的uri,UrlPathHelper是个好东西,还可以做很多事情。仔细研究一下这个方法:

/**
     * Return the request URI for the given request. If this is a forwarded request,
     * correctly resolves to the request URI of the original request.
     */
    public String getOriginatingRequestUri(HttpServletRequest request) {
        String uri = (String) request.getAttribute(WEBSPHERE_URI_ATTRIBUTE);
        if (uri == null) {
            uri = (String) request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE);
            if (uri == null) {
                uri = request.getRequestURI();
            }
        }
        return decodeAndCleanUriString(request, uri);
    }
 

针对websphere和其他的web容器有不同的方式,但是基础方式都是从request的属性中获取forward之前的uri,自从servlet2.4版本之后,request内部其实有一个属性存储了这个值,这个属性的名字是: /**

     * Special WebSphere request attribute, indicating the original request URI.
     * Preferable over the standard Servlet 2.4 forward attribute on WebSphere,
     * simply because we need the very first URI in the request forwarding chain.
     */
    private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded";

 

/**
   57   	 * Standard Servlet 2.4+ spec request attributes for forward URI and paths.
   58   	 * <p>If forwarded to via a RequestDispatcher, the current resource will see its
   59   	 * own URI and paths. The originating URI and paths are exposed as request attributes.
   60   	 */
   61   	public static final String FORWARD_REQUEST_URI_ATTRIBUTE = "javax.servlet.forward.request_uri";

 

参照代码:

http://www.docjar.com/html/api/org/springframework/web/util/WebUtils.java.html

http://www.docjar.com/html/api/org/springframework/web/util/WebUtils.java.html

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值