我在jboss容器中部署了两个应用程序(同一个unix框)。如果我从app1收到请求,我需要为app2构建相应的请求。
例如
如果app1请求是:http://example.com/context?param1=123
然后我需要提取“http://example.com/”,以便我可以构建第二个应用程序的请求。
我尝试使用:
HttpServletRequest.getServerName() &
HttpServletRequest.getServerPort() & \
HttpServletRequest.getHeader("host")
方法,但请求可能是http或https。
如果还有其他更好的方法,请告诉我。 谢谢!
答案 0 :(得分:40)
您可以使用HttpServletRequest.getScheme()
检索“http”或“https”。
将它与HttpServletRequest.getServerName()
一起使用就足以重建所需网址的一部分。
如果您使用标准端口,则无需在URL中明确放置端口(对于http为80,对于https为443)。
编辑:如果您的servlet容器位于终止SSL的反向代理或负载均衡器后面,那就有点棘手,因为请求会以纯http的形式转发到servlet容器。您有几个选择:
1)改为使用HttpServletRequest.getHeader("x-forwarded-proto")
;这只适用于负载均衡器正确设置标头(Apache应该是afaik)。
2)在JBoss / Tomcat中配置一个RemoteIpValve,使getScheme()
按预期工作。同样,这仅在负载均衡器设置正确的标头时才有效。
3)如果上述方法不起作用,您可以在Tomcat / JBoss中配置两个不同的连接器,一个用于http,另一个用于https,如this article中所述。
答案 1 :(得分:17)
您可以使用HttpServletRequest.getRequestURL和HttpServletRequest.getRequestURI。
StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
String host = url.substring(0, url.indexOf(uri)); //result
答案 2 :(得分:3)
如果您想要原始网址,请使用jthalborn所述的方法。 如果你想重建网址就像David Levesque解释的那样,这里有一个代码片段:
final javax.servlet.http.HttpServletRequest req = (javax.servlet.http.HttpServletRequest) ...;
final int serverPort = req.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
// No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
url = String.format("%s://%s/...", req.getScheme(), req.getServerName(), ...);
} else {
url = String.format("%s://%s:%s...", req.getScheme(), req.getServerName(), serverPort, ...);
}
您仍然需要考虑反向代理的情况:
可以为端口使用常量,但不确定是否有可靠的源,默认端口:
大多数开发人员无论如何都会知道端口80和443,因此常量没有用。
另请参见此类post。
答案 3 :(得分:3)
如果您使用负载平衡器& Nginx,在没有修改代码的情况下配置它们。
Nginx的:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Tomcat的server.xml引擎:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
如果只修改Nginx配置文件,则java代码应为:
String XForwardedProto = request.getHeader("X-Forwarded-Proto");
答案 4 :(得分:1)
请参阅http://docs.oracle.com/javase/tutorial/networking/urls/urlInfo.html。这是关于url解析的最简洁的报道。
答案 5 :(得分:1)
似乎您需要从URL中剥离URL,因此可以通过以下方式进行操作:
request.getRequestURL().toString().replace(request.getRequestURI(), "")
答案 6 :(得分:0)
如果您的服务器在代理服务器后面运行,请确保已设置代理标头:
proxy_set_header X-Forwarded-Proto $scheme;
然后要获得正确的scheme & url
,可以使用springframework的类:
public String getUrl(HttpServletRequest request) {
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents uriComponents = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
String scheme = uriComponents.getScheme(); // http / https
String serverName = request.getServerName(); // hostname.com
int serverPort = request.getServerPort(); // 80
String contextPath = request.getContextPath(); // /app
// Reconstruct original requesting URL
StringBuilder url = new StringBuilder();
url.append(scheme).append("://");
url.append(serverName);
if (serverPort != 80 && serverPort != 443) {
url.append(":").append(serverPort);
}
url.append(contextPath);
return url.toString();
}
答案 7 :(得分:0)
我参加聚会很晚,但是在使用Java 8时遇到了同样的问题。
这是对HttpServletRequest request
对象有用的东西。
request.getHeader("origin");
和
request.getHeader("referer");
我如何得出这个结论:
我有一个在 http://localhost:3000 上运行的Java应用程序,向我在 http://localhost:8080 上运行的另一个Java应用程序发出Http Post。
从运行在 http://localhost:8080 的Java代码中,我无法使用 HttpServletRequest 从 http://localhost:3000 上面的答案。对我来说,使用getHeader
方法和正确的字符串输入有效。
request.getHeader("origin")
给了我“ http://localhost:3000” 。
request.getHeader("referer")
给了我“ http://localhost:3000/xxxx” ,其中xxxx是我来自请求应用程序的完整URL。