I have two applications deployed in jboss container(same unix box). If i get a request from app1, i need to frame a corresponding request for app2.
eg:
if app1 request is: http://example.com/context?param1=123
then I need to extract "http://example.com/", so that I can frame request for second app.
I tried using:
HttpServletRequest.getServerName() &
HttpServletRequest.getServerPort() & \
HttpServletRequest.getHeader("host")
methods, but the request may be of http or https.
Please let me know if there is any other better way. Thanks!
This question is related to
java
http
servlets
http-headers
httprequest
Seems like you need to strip the URL from the URL, so you can do it in a following way:
request.getRequestURL().toString().replace(request.getRequestURI(), "")
I'm late to the party, but I had this same issue working with Java 8.
This is what worked for me, on the HttpServletRequest request
object.
request.getHeader("origin");
and
request.getHeader("referer");
How I came to that conclusion:
I have a java app running on http://localhost:3000 making a Http Post to another java app I have running on http://localhost:8080.
From the Java code running on http://localhost:8080 I couldn't get the http://localhost:3000 from the HttpServletRequest using the answers above. For me using the getHeader
method with the correct string input worked.
request.getHeader("origin")
gave me "http://localhost:3000" which is what I wanted.
request.getHeader("referer")
gave me "http://localhost:3000/xxxx" where xxxx is full URL I have from the requesting app.
You can use HttpServletRequest.getRequestURL and HttpServletRequest.getRequestURI.
StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
int idx = (((uri != null) && (uri.length() > 0)) ? url.indexOf(uri) : url.length());
String host = url.substring(0, idx); //base url
idx = host.indexOf("://");
if(idx > 0) {
host = host.substring(idx); //remove scheme if present
}
If you use the load balancer & Nginx, config them without modify code.
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's server.xml Engine:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
If only modify Nginx config file, the java code should be:
String XForwardedProto = request.getHeader("X-Forwarded-Proto");
If your server is running behind a proxy server, make sure your proxy header is set:
proxy_set_header X-Forwarded-Proto $scheme;
Then to get the right scheme & url
you can use springframework's classes:
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();
}
If you want the original URL just use the method as described by jthalborn. If you want to rebuild the url do like David Levesque explained, here is a code snippet for it:
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, ...);
}
You still need to consider the case of a reverse-proxy:
Could use constants for the ports but not sure if there is a reliable source for them, default ports:
Most developers will know about port 80 and 443 anyways, so constants are not that helpful.
Also see this similar post.
Source: Stackoverflow.com