【发布时间】:2010-12-02 05:26:35
【问题描述】:
我想根据客户端用于活动请求的 URL 创建 URL。有什么比采用当前的 HttpServletRequest 对象更聪明的方法,它是 getParameter...() 方法来重建完整的 URL,包括(且仅)它的 GET 参数。
澄清:如果可能,我想放弃使用HttpServletRequest 对象。
【问题讨论】:
标签: url spring-mvc httprequest
我想根据客户端用于活动请求的 URL 创建 URL。有什么比采用当前的 HttpServletRequest 对象更聪明的方法,它是 getParameter...() 方法来重建完整的 URL,包括(且仅)它的 GET 参数。
澄清:如果可能,我想放弃使用HttpServletRequest 对象。
【问题讨论】:
标签: url spring-mvc httprequest
嗯,有两种方法可以更轻松地访问这些数据,但该界面不提供一次调用获取整个 URL 的可能性。您必须手动构建它:
public static String makeUrl(HttpServletRequest request)
{
return request.getRequestURL().toString() + "?" + request.getQueryString();
}
我不知道如何使用任何 Spring MVC 工具来做到这一点。
如果您想访问当前请求而不将其传递到任何地方,您必须在 web.xml 中添加一个侦听器:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
然后用这个来获取绑定到当前线程的请求:
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()
【讨论】:
HttpServletRequest 对象的方法。这是因为我使用了几个辅助类/方法,我不想每次都传递请求对象。
UrlUtils 结合使用。像魅力一样工作。
除了直接使用RequestContextHolder,还可以使用ServletUriComponentsBuilder及其静态方法:
ServletUriComponentsBuilder.fromCurrentContextPath()ServletUriComponentsBuilder.fromCurrentServletMapping()ServletUriComponentsBuilder.fromCurrentRequestUri()ServletUriComponentsBuilder.fromCurrentRequest()它们在底层使用RequestContextHolder,但提供了额外的灵活性来使用UriComponentsBuilder 的功能构建新的URL。
例子:
ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
builder.scheme("https");
builder.replaceQueryParam("someBoolean", false);
URI newUri = builder.build().toUri();
【讨论】:
ConstraintValidator 和 ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString(); 中获取 URL。
Java 的 URI 类可以帮你解决这个问题:
public static String getCurrentUrl(HttpServletRequest request){
URL url = new URL(request.getRequestURL().toString());
String host = url.getHost();
String userInfo = url.getUserInfo();
String scheme = url.getProtocol();
String port = url.getPort();
String path = request.getAttribute("javax.servlet.forward.request_uri");
String query = request.getAttribute("javax.servlet.forward.query_string");
URI uri = new URI(scheme,userInfo,host,port,path,query,null)
return uri.toString();
}
【讨论】:
在jsp文件中:
request.getAttribute("javax.servlet.forward.request_uri")
【讨论】:
您还可以在控制器方法的方法签名中添加UriComponentsBuilder。 Spring 将注入从当前请求创建的构建器实例。
@GetMapping
public ResponseEntity<MyResponse> doSomething(UriComponentsBuilder uriComponentsBuilder) {
URI someNewUriBasedOnCurrentRequest = uriComponentsBuilder
.replacePath(null)
.replaceQuery(null)
.pathSegment("some", "new", "path")
.build().toUri();
//...
}
使用构建器,您可以根据当前请求直接开始创建 URI,例如修改路径段。
【讨论】:
UriComponentsBuilder不包含请求的路径和查询参数。如果您需要访问这些,请使用ServletUriComponentsBuilder.fromCurrentRequest() 或注入HttpServletRequest 的实例并使用ServletUriComponentsBuilder.fromRequest(request)
如果您需要 URL 直到主机名而不是路径,请使用 Apache 的 Common Lib StringUtil,并从 URL 中提取子字符串直到第三个 indexOf /。
public static String getURL(HttpServletRequest request){
String fullURL = request.getRequestURL().toString();
return fullURL.substring(0,StringUtils.ordinalIndexOf(fullURL, "/", 3));
}
示例:如果 fullURL 是 https://example.com/path/after/url/ 那么
输出将是https://example.com
【讨论】:
System.out.println(((HttpServletRequest)request).getRequestURI());
我用过。希望有用。
【讨论】: