Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-redirect root path to Spring Boot Context Path

I am using Spring Boot Context Path as specified in the application.properties file, and it works great

server.port=5000
server.context-path=/services

Spring Boot 2.0 and above

server.port=5000
server.servlet.context-path=/services

But how can we achieve default redirect of root i.e. “/” to “/services”

http://localhost:5000/services - works great!

But I want http://localhost:5000/ to automatically redirect to -> http://localhost:5000/services so that an end user should be able to access the root of the domain and be automatically redirected to the context path

Currently accessing the root is throwing a 404 (which makes sense with the default configuration)

How can I achieve the automatic redirect of root i.e. “/” to the context path?

like image 424
Rahul Kargwal Avatar asked May 17 '19 14:05

Rahul Kargwal


People also ask

How do I change the default context path in spring boot?

Just like many other configuration options, the context path in Spring Boot can be changed by setting a property, server. servlet. context-path. Note that this works for Spring Boot 2.

How do I redirect a URL in spring boot?

We can use a name such as a redirect: http://localhost:8080/spring-redirect-and-forward/redirectedUrl if we need to redirect to an absolute URL.

How do I redirect a URL in spring boot RestController?

@RestController public class RedirectController { @RequestMapping("/redirect") public String redirect() { return "redirect:/other/controller/"; } } and if we will try to access that url curl localhost:8080/redirect we will simply see redirect:/other/controller/ string as result.

Can we have multiple context path in spring boot?

In order to have multiple context paths, you're limited to deploying the application multiple times with that convenient property set to what you want for each deployment. However, this is resource expensive because you're spinning up two applications for every one application you would normally spin up.


2 Answers

I think I can provide a solution.Please refer to the following code.

@Configuration
public class RootServletConfig {

    @Bean
    public TomcatServletWebServerFactory servletWebServerFactory() {
        return new TomcatServletWebServerFactory() {

            @Override
            protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
                super.prepareContext(host, initializers);
                StandardContext child = new StandardContext();
                child.addLifecycleListener(new Tomcat.FixContextListener());
                child.setPath("");
                ServletContainerInitializer initializer = getServletContextInitializer(getContextPath());
                child.addServletContainerInitializer(initializer, Collections.emptySet());
                child.setCrossContext(true);
                host.addChild(child);
            }
        };
    }

    private ServletContainerInitializer getServletContextInitializer(String contextPath) {
        return (c, context) -> {
            Servlet servlet = new HttpServlet() {
                @Override
                protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                    resp.sendRedirect(contextPath);
                }
            };
            context.addServlet("root", servlet).addMapping("/*");
        };
    }
}
like image 177
HAOQI WANG Avatar answered Sep 27 '22 22:09

HAOQI WANG


It seems that you cannot do this simply. Setting server.servlet.context-path=/services sets your server's root path to /services. And when you redirect a path with / - in fact, you are redirecting with a path /services. Here's what I tried to solve this problem:

  • If you have an intermediate web server in front of your application (apache, nginx) - you can do a redirect in its settings.
  • Or you can replace the server.servlet.context-path setting with your own pathname something like this:
    app.endpoints.services_path=/services in application.config
    @RequestMapping("${app.endpoints.services_path}") mapping in Controller.
    And after that make a redirect from the path / to /services.

For example, in one of these ways:

  • With a redirect controller
@Controller
public class RootRedirectController {
    @GetMapping(value = "/")
    public void redirectToServices(HttpServletResponse httpServletResponse){
        httpServletResponse.setHeader("Location", "/services");
        httpServletResponse.setStatus(302);
    }
}
  • Or by adding customization to Spring Boot
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/services");
        // This method can be blocked by the browser!
        // registry.addRedirectViewController("/", "redirect:/services");
    }
}

Hope this helps. Sorry my Google Translate.

like image 37
Dimio Avatar answered Sep 27 '22 22:09

Dimio