Explain Codes LogoExplain Codes Logo

Httpservletrequest to complete URL

java
string-assembly
url-construction
performance-optimization
Alex KataevbyAlex Kataev·Feb 23, 2025
TLDR

To create the full URL from an HttpServletRequest, you should append the scheme, server name, and context path to the request URI. Include the query string, if it's present. Also, check if the port should be included (omit it if it's the default HTTP/HTTPS port). Here's an example of how you can do it:

HttpServletRequest request; // Assume it's already initialized. String scheme = request.getScheme(); // Either http or https. String serverName = request.getServerName(); // Extracts the domain name. int serverPort = request.getServerPort(); // Captures the used port number. String contextPath = request.getContextPath(); // Fetches the web app (or "context") name. String servletPath = request.getServletPath(); // Fetches the path to the servlet handling the request. String pathInfo = request.getPathInfo(); // Fetches any extra path information. String queryString = request.getQueryString(); // Extracts everything after "?" in the URL. // The superhero section: where all these powerful parts unite to form the // super URL. It's like Avengers assemble, but for web developers! String fullUrl = scheme + "://" + serverName + ((serverPort == 80 || serverPort == 443) ? "" : ":" + serverPort) + contextPath + servletPath + (pathInfo == null ? "" : pathInfo) + (queryString == null ? "" : "?" + queryString);

This approach checks port usage and query string presence dynamically to produce a compact, ready-to-use URL.

Strengthen your URL construction with StringBuilder

In Java, StringBuilder can significantly boost performance during string assembly (especially in loops or repetitive operations) due to its mutable nature. When building the complete URL, consider employing StringBuilder for efficient URL assembly.

// Start of the Avengers assemble...againity! StringBuilder avengers = new StringBuilder(); avengers.append(scheme).append("://") .append(serverName) .append(serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) .append(contextPath) .append(servletPath) .append(pathInfo == null ? "" : pathInfo) .append(queryString == null ? "" : "?" + queryString); // And the super URL is born! String fullUrl = avengers.toString();

Cunning tricks and lurking dangers in URL construction

Tackling the non-standard ports beast

If your application sometimes feels adventurous and runs on non-standard ports, extra caution should be taken to ensure their proper inclusion. Otherwise, an incorrect URL formation may result.

Crosses swords with encoded query strings

Encoded query strings should be handled with precision. If your query string has special characters, make sure to slay them with proper encoding before appending:

String encodedQuery = URLEncoder.encode(request.getQueryString(), "UTF-8"); // Now, you can append 'encodedQuery' to URL (considering if it's not null) without fear!

Shiny UriComponentsBuilder armor

Consider using UriComponentsBuilder from the Spring Framework as additional protective gear. It provides a more sturdy and neat approach:

// Let's celebrate this epic victory with UriComponentsBuilder! UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(request.getRequestURL().toString()); if (queryString != null) { builder.query(queryString); } String fullUrl = builder.toUriString();

This technique takes care of the proper encoding of the query string and is less prone to errors.

Battle of the servlet containers

Remember, not all servlet containers are created equal (Tomcat, Jetty, you name it). Their subtle differences can impact your URL construction. Always test your URL formation battleground against your actual servlet container.

Out-of-the-box scenarios and pro tips

Underneath the cloak of a proxy or load balancer

When your application is running behind a proxy or load balancer, the knights request.getScheme() and request.getServerName() may not return the actual values the client used. You must use X-Forwarded-* headers to fetch the original URL details:

String trueScheme = request.getHeader("X-Forwarded-Proto"); String trueServerName = request.getHeader("X-Forwarded-Host"); // Use these noble headers instead of getScheme() and getServerName() if they're not null.

Retaining the session's magical scroll (session information)

If you wish to retain the session ID in the URL (*gasp*, cookies are disabled!), you can enchant your URL with HttpServletResponse.encodeURL(fullUrl). This spell appends the JSESSIONID.

Security, the noble knight of coding realm

You should be careful when using full URL in redirects or responses. The demon of open redirect vulnerabilities lurks here. Always validate your URLs that are built based on user input to defend your realm.