Get Root/Base Url In Spring MVC
Asked Answered
T

15

59

What is the best way to get the root/base url of a web application in Spring MVC?

Base Url = http://www.example.com or http://www.example.com/VirtualDirectory

Tenstrike answered 16/2, 2011 at 4:25 Comment(3)
Where do you need this? In a controller or in a JSP page?Figurative
Everywhere within a website that has access to the contest/request/response to get it.Tenstrike
ServletUriComponentsBuilder.fromCurrentServletMapping().toUriString()Yearning
J
29

If base url is "http://www.example.com", then use the following to get the "www.example.com" part, without the "http://":

From a Controller:

@RequestMapping(value = "/someURL", method = RequestMethod.GET)
public ModelAndView doSomething(HttpServletRequest request) throws IOException{
    //Try this:
    request.getLocalName(); 
    // or this
    request.getLocalAddr();
}

From JSP:

Declare this on top of your document:

<c:set var="baseURL" value="${pageContext.request.localName}"/> //or ".localAddr"

Then, to use it, reference the variable:

<a href="http://${baseURL}">Go Home</a>
Jura answered 30/3, 2013 at 13:1 Comment(3)
or, from the JSP you can set the value of the "baseURL" variable dirrectly with the "http://" prefixJura
he method getLocalAddr() is undefined for the type HttpServletRequestIllogic
Tbh you shouldn't use this as it's quite an old answer and is not up to date anymore. Have a look at my answer #5013025Aldershot
B
73

I prefer to use

final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();

It returns a completely built URL, scheme, server name and server port, rather than concatenating and replacing strings which is error prone.

Bushel answered 22/12, 2018 at 15:31 Comment(5)
I was looking for this one because this can be used everywhere, even at app startup.Cute
It's what I was looking for!Obi
It does not work: java.lang.IllegalStateException: No current ServletRequestAttributes I'm using it in @EventListener(ApplicationReadyEvent.class) handler, trying to use app base url for something, but it does not work. SpringBoot 2.1.7Polite
Same here, I get that error anywhere but in the controller. I think it needs a request context to work.Apostasy
This does not return the base URL. It instead returns the full request URL.Westing
J
29

If base url is "http://www.example.com", then use the following to get the "www.example.com" part, without the "http://":

From a Controller:

@RequestMapping(value = "/someURL", method = RequestMethod.GET)
public ModelAndView doSomething(HttpServletRequest request) throws IOException{
    //Try this:
    request.getLocalName(); 
    // or this
    request.getLocalAddr();
}

From JSP:

Declare this on top of your document:

<c:set var="baseURL" value="${pageContext.request.localName}"/> //or ".localAddr"

Then, to use it, reference the variable:

<a href="http://${baseURL}">Go Home</a>
Jura answered 30/3, 2013 at 13:1 Comment(3)
or, from the JSP you can set the value of the "baseURL" variable dirrectly with the "http://" prefixJura
he method getLocalAddr() is undefined for the type HttpServletRequestIllogic
Tbh you shouldn't use this as it's quite an old answer and is not up to date anymore. Have a look at my answer #5013025Aldershot
A
19

Explanation

I know this question is quite old but it's the only one I found about this topic, so I'd like to share my approach for future visitors.

If you want to get the base URL from a WebRequest you can do the following:

ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request);

This will give you the scheme ("http" or "https"), host ("example.com"), port ("8080") and the path ("/some/path"), while fromRequest(request) would give you the query parameters as well. But as we want to get the base URL only (scheme, host, port) we don't need the query params.

Now you can just delete the path with the following line:

ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request).replacePath(null);

TLDR

Finally our one-liner to get the base URL would look like this:

//request URL: "http://example.com:8080/some/path?someParam=42"

String baseUrl = ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request)
        .replacePath(null)
        .build()
        .toUriString();

//baseUrl: "http://example.com:8080"

Addition

If you want to use this outside a controller or somewhere, where you don't have the HttpServletRequest present, you can just replace

ServletUriComponentsBuilder.fromRequestUri(HttpServletRequest request).replacePath(null)

with

ServletUriComponentsBuilder.fromCurrentContextPath()

This will obtain the HttpServletRequest through spring's RequestContextHolder. You also won't need the replacePath(null) as it's already only the scheme, host and port.

Aldershot answered 5/9, 2019 at 7:56 Comment(2)
Unfortunately, this works only in a bean or a controller. Searching for a solution to add the application server URL in generated PDFs for almost 2 days, no luck :( Getting java.lang.IllegalStateException: No current ServletRequestAttributes outside the controllers and beans.Midweek
Be careful using this solution with the call replacePath(null) as it loses the application's root context (eg set via the server.servlet.context-path application property). The version that uses just ServletUriComponentsBuilder.fromCurrentContextPath() without the call to replacePath(null) automatically includes the app context root, so works as intended.Blatant
G
18

You can also create your own method to get it:

public String getURLBase(HttpServletRequest request) throws MalformedURLException {

    URL requestURL = new URL(request.getRequestURL().toString());
    String port = requestURL.getPort() == -1 ? "" : ":" + requestURL.getPort();
    return requestURL.getProtocol() + "://" + requestURL.getHost() + port;

}
Galina answered 14/3, 2016 at 2:45 Comment(1)
The problem with this is that the URL is taken from the request. Meaning, if a certificate is signed for *.example.com, which resolves to 192.168.42.1 and the request was made with the IP address instead of the name, it will cause issues. The best way is to configure (hard code) the name somewhere in the application's configuration. This way, when sending things like emails, your emails will be more legit and trusted.Calkins
M
12

Simply :

/*
 * Returns the base URL from a request.
 *
 * @example: http://myhost:80/myapp
 * @example: https://mysecuredhost:443/
 */
String getBaseUrl(HttpServletRequest req) {
  return ""
    + req.getScheme() + "://"
    + req.getServerName()
    + ":" + req.getServerPort()
    + req.getContextPath();
}
Mabuse answered 27/7, 2017 at 0:4 Comment(4)
Best answer in the world.Cassimere
Really great answerAdvised
where to add this codeAssert
@vanisaladhagu you can add it in a utility class, just make the method static you could call it from anywhere like RequestUtil.getBaseUrl(httpRequest)Mabuse
S
11

request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath())

Sight answered 4/3, 2015 at 10:17 Comment(3)
Whats the difference between getRequestURL and getRequestURI?Transparency
take a look at this link coderanch.com/t/360343/java/request-getURL-request-getURISight
Note: this doesn't work if you request URI is just "/" as it strips the slashes from the protocol.Piecemeal
S
9

In controller, use HttpServletRequest.getContextPath().

In JSP use Spring's tag library: or jstl

Sedan answered 26/10, 2012 at 16:43 Comment(0)
S
8

Either inject a UriCompoenentsBuilder:

@RequestMapping(yaddie yadda)
public void doit(UriComponentBuilder b) {
  //b is pre-populated with context URI here
}

. Or make it yourself (similar to Salims answer):

// Get full URL (http://user:[email protected]/root/some?k=v#hey)
URI requestUri = new URI(req.getRequestURL().toString());
// and strip last parts (http://user:[email protected]/root)
URI contextUri = new URI(requestUri.getScheme(), 
                         requestUri.getAuthority(), 
                         req.getContextPath(), 
                         null, 
                         null);

You can then use UriComponentsBuilder from that URI:

// http://user:[email protected]/root/some/other/14
URI complete = UriComponentsBuilder.fromUri(contextUri)
                                   .path("/some/other/{id}")
                                   .buildAndExpand(14)
                                   .toUri();
Smaragd answered 7/12, 2015 at 13:0 Comment(2)
Thanks for the intro to UriComponentBuilder - I've never used it before. Very useful.Franctireur
No problem, glad I could help.Smaragd
C
2

In JSP

<c:set var="scheme" value="${pageContext.request.scheme}"/>
<c:set var="serverPort" value="${pageContext.request.serverPort}"/>
<c:set var="port" value=":${serverPort}"/>

<a href="${scheme}://${pageContext.request.serverName}${port}">base url</a>

reference https://github.com/spring-projects/greenhouse/blob/master/src/main/webapp/WEB-INF/tags/urls/absoluteUrl.tag

Cottonmouth answered 11/12, 2016 at 5:54 Comment(0)
B
1
     @RequestMapping(value="/myMapping",method = RequestMethod.POST)
      public ModelandView myAction(HttpServletRequest request){

       //then follow this answer to get your Root url
     }

Root URl of the servlet

If you need it in jsp then get in in controller and add it as object in ModelAndView.

Alternatively, if you need it in client side use javascript to retrieve it: http://www.gotknowhow.com/articles/how-to-get-the-base-url-with-javascript

Butlery answered 16/2, 2011 at 10:22 Comment(1)
Personally, I would use this answer to get it in a JSP: #4278945Figurative
T
0

I think the answer to this question: Finding your application's URL with only a ServletContext shows why you should use relative url's instead, unless you have a very specific reason for wanting the root url.

Tocci answered 21/9, 2011 at 12:37 Comment(0)
S
0

If you just interested in the host part of the url in the browser then directly from request.getHeader("host")) -

import javax.servlet.http.HttpServletRequest;

@GetMapping("/host")
public String getHostName(HttpServletRequest request) {

     request.getLocalName() ; // it will return the hostname of the machine where server is running.

     request.getLocalName() ; // it will return the ip address of the machine where server is running.


    return request.getHeader("host"));

}

If the request url is https://localhost:8082/host

localhost:8082

Sunbeam answered 1/4, 2020 at 10:39 Comment(0)
V
0

Here:

In your .jsp file inside the [body tag]

<input type="hidden" id="baseurl" name="baseurl" value=" " />

In your .js file

var baseUrl = windowurl.split('://')[1].split('/')[0]; //as to split function 
var xhr = new XMLHttpRequest();
var url='http://'+baseUrl+'/your url in your controller';
xhr.open("POST", url); //using "POST" request coz that's what i was tryna do
xhr.send(); //object use to send```
Voorhis answered 16/12, 2020 at 12:26 Comment(1)
Welcome to SO! Please read the tour, and How do I write a good answer?Techy
W
0

I had the exact requirement and reached to below solution:

String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath()
                    .replacePath(null).replaceQuery(null).fragment(null).build().toUriString();

For this code to work, it should run inside a thread bound to a Servlet request.

Westing answered 16/4, 2023 at 15:0 Comment(0)
K
0

The following worked for me:

In the controller method, add a parameter of type HttpServletRequest. You can have this parameter and still have an @RequestBody parameter, which is what all the previous answers fail to mention.

@PostMapping ("/your_endpoint")
public ResponseEntity<Object> register(
   HttpServletRequest servletRequest,
   @RequestBody RegisterRequest request
) {

    String url = servletRequest.getRequestURL().toString();
    String contextPath = servletRequest.getRequestURI();
    String baseURL = url.replace(contextPath,"");

    /// .... Other code 

}

I tested this on Spring Boot 3.0.6.

Kindred answered 26/5, 2023 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.