Retrieving the servlet context path from a Spring web application
Asked Answered
S

5

43

I would like to be able to dynamically retrieve the "servlet context path" (e.g. http://localhost/myapp or http://www.mysite.com) for my spring web application from a Service spring bean.

The reason for this is that I want to use this value in email that are going to be sent to users of the website.

While it would be pretty easy to do this from a Spring MVC controller, it is not so obvious to do this from a Service bean.

Can anyone please advise?

EDIT: Additional requirement:

I was wondering if there wasn't a way of retrieving the context path upon startup of the application and having it available for retrieval at all time by all my services?

Silurian answered 2/9, 2012 at 14:4 Comment(1)
perhaps it's time to mark the question as solved...Anchovy
U
61

If you use a ServletContainer >= 2.5 you can use the following code to get the ContextPath:

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component

@Component
public class SpringBean {

    @Autowired
    private ServletContext servletContext;

    @PostConstruct
    public void showIt() {
        System.out.println(servletContext.getContextPath());
    }
}
Unclose answered 26/2, 2013 at 7:57 Comment(1)
See also this answer to a related question: https://mcmap.net/q/197007/-get-web-app-root-from-spring-controllerAnatola
M
31

As Andreas suggested, you can use the ServletContext. I use it like this to get the property in my components:

    @Value("#{servletContext.contextPath}")
    private String servletContextPath;
Microbe answered 14/12, 2015 at 9:13 Comment(4)
do you know how can I inject this value into my js files ?Illustrate
Different question. Personally I would use an API. Otherwise you would need to preprocess your JS files.Microbe
@Wilson Campusano - to inject into js file , I do in my JSP page <script>window.contextPath = ${pageRequest.request.contextPath}</script> .Then in my js I reference it as window.contextPathHaun
@VishnooRath Thank you! that was what I did.Illustrate
S
6

I would avoid creating a dependency on the web layer from your service layer. Get your controller to resolve the path using request.getRequestURL() and pass this directly to the service:

String path = request.getRequestURL().toString();
myService.doSomethingIncludingEmail(..., path, ...);
Syblesybley answered 2/9, 2012 at 19:1 Comment(5)
Thanks Rich! I was wondering if there wasn't a way of retrieving the context path upon startup of the application and having it available for retrieval at all time by all my services?Silurian
You could set the path in the configuration of the service. Though I can't see how you can retrieve this automatically from the servlet configuration.Syblesybley
Yes. Hummmm... But how do I retrieve it upon startup of the application?Silurian
No idea sorry, I think only the servlet container would know this value.Syblesybley
OK. I just wanted this value available before any user httprequest is done. I'll research the matter and post here accordingly.Silurian
D
2

If the service is triggered by a controller, which I am assuming it is you can retrieve the path using HttpSerlvetRequest from the controller and pass the full path to the service.

If it is part of the UI flow, you can actually inject in HttpServletRequest in any layer, it works because if you inject in HttpServletRequest, Spring actually injects a proxy which delegates to the actual HttpServletRequest (by keeping a reference in a ThreadLocal).

import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;

public class AServiceImpl implements AService{

 @Autowired private HttpServletRequest httpServletRequest;


 public String getAttribute(String name) {
  return (String)this.httpServletRequest.getAttribute(name);
 }
}
Darryldarryn answered 2/9, 2012 at 15:6 Comment(2)
How do you @Autowire in a HttpServletRequest to a service? Surely the request is not available at this point?Syblesybley
Yes, you are right, that is the reason why I indicated that this has to be part of a UI flow - some request from the user to controller to this service triggering an email, if that is not the case yes then this will not work. The best I can then think of is to get the context path of the webapp using HttpServletContext injected by declaring your service as ServletContextAware, but the URL will have to be based off a configuration fileDarryldarryn
G
1

With Spring Boot, you can configure the context-path in application.properties:

server.servlet.context-path=/api

You can then get the path from a Service or Controller like this:

import org.springframework.beans.factory.annotation.Value;

@Value("${server.servlet.context-path}")
private String contextPath;
Grummet answered 25/1, 2021 at 13:24 Comment(1)
Afaict this is only applicable to the embedded tomcat with spring-boot.Gaudy

© 2022 - 2024 — McMap. All rights reserved.