简体   繁体   中英

How do I find base URL during Spring MVC startup?

fellow programmers who lurks here at Stack Overflow.

Today's question: How can I get the absolute baseUrl in Spring MVC Framework, from startup?

I'm working with Spring MVC Framework for an application, and I'm in this situation: Let's say that I need to make objects of class Foo, inserted into a list. Every object contains an unique self-link (I'm using org.springframework.hateoas.Link for the real application, but that's beside the point).

Example code:

class Foo{
    private int ID;
    private String absoluteUrl;

    public Foo(int ID, String baseUrl){
        this.ID = ID;
        this.absoluteUrl = baseUrl + ID; 
    }

    public void setAbsoluteUrl(String baseUrl){
        this.absoluteUrl = baseUrl + this.ID;
    }
}

If I run it through a factory, it could look something like this:

public List<Foo> GenerateFooList(String baseUrlFetchedBySpring){
    List<Foo> list = new ArrayList();
    for (int i = 0; i<100; i++){
    list.add(new Foo(i, baseUrlFetchedBySpring);
    return list;
}

Resulting baseadresses I would expect during the test phase would be " http://localhost:8000 " (or hypothetically, at production, " http://www.fooExample.com ").

My issue: I need to get the baseUrl from Spring MVC Framework, at startup.

The Spring MVC application I'm working with is configured by annotations only. I have found out that one can get an absolute url by using HttpServletRequest.getRequestURL().toString(), but to my understanding the application receives these after startup, while I need the baseUrl from the beginning. After all, the Spring API describes HttpServletRequest as: "Defines an object to provide client request information to a servlet", in other words a request sent from a client after startup.

I could of course add a static baseUrl by writing a private final String in the code:

private final String BASE_URL = "http://www.fooExample.com/"

But in case of changes on the application's base-url over time, it would be better if the base url could be set automaticly by Spring MVC. Let's say that I have a Cache-class, that uses dependency injection:

@Repository
class FooCache{

    List<Foo> list;
    SpringObject springObject; // = ???????????

    @Autowired
    public FooCache(SpringObject springObject){
        this.springObject = springObject; // = ???????????
        initCache();
    }

    public void initCache(){
        for (int i = 0; i<100; i++){
        list.add(new Foo(i, springObject.getAbsoluteBaseUrl()); // method = ???????????
    }
}

This is more of what I am looking for: The cache is only set once, at the beginning, using an object from Spring that contains the information I need. Most likely, it's a config-class that is part of the framework, but after searching for a while on the Internet, what I mostly find is HttpServletRequest-related solutions.

What Spring class/object and method am I truly looking for? Or what other suggestions do you have to fetch the base_url from the beginning?

I need the absolute base url for this one, not something relative.

There is no single "base URL" for your application. Think about it - you can access your production server:

  • via different domain names
  • via IP
  • SSH to it and access via "localhost"
  • via HTTP and HTTPS

If you don't want to or cannot reflect the "base URL" of the request, my suggestion would be to have one "canonical base URL" configured per environment eg. in the properties. But that's up to you if it makes sense in your case.

If you're using java config and Servlet 3.0+ style (without web.xml), you could have a WebApplicationInitializer implementation such as:

public class MyWebApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());
        registration.setLoadOnStartup(1);
        registration.addMapping("/example/*");
    }

}

with this arrangement, you could use servletContext.getContextPath() to get base url.

You have no way of knowing that without a request. You could use InetAddress and resolve host information, but I am guessing that is not what you are looking for.

Let's say you have two domains www.foo.com and www.bar.com pointing to the host where your application is running. On startup you have no information about any of that, you would have to do a reverse DNS search. When you get a request, you have the information where it is coming from.

You should fill the links on request so you can get rid of caching request scope information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM