12

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?

Rahul Kargwal
  • 487
  • 1
  • 5
  • 20

2 Answers2

13

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("/*");
        };
    }
}
HAOQI WANG
  • 146
  • 2
  • 4
  • Works perfectly for me. This solution adds a root servlet that redirects, similar what was suggested for the classic Tomcat: https://stackoverflow.com/questions/30490642/tomcat-redirect-old-context-root-to-new-context-root – SP193 Dec 23 '21 at 03:30
  • how to do this with undertow instead of embedded tomcat – jathin sanghvi Jun 29 '22 at 16:29
2

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.

Dimio
  • 51
  • 1
  • 6