zhy1378
zhy1378

Reputation: 329

A new Spring ServletDispatcher/ HandlerMapping redirect request based on domain name

I'm using Spring + Gradle + PostgreSQL, and I want to write a new Spring ServletDispatcher or HandlerMapping (I don't know which one is the best choice).

The requirement is: Redirect the HTTP request to different controller according to it's sub domain name.

For example:

HTTP request to:
aaa.domain.com will be redirect to => websites/aaa/
bbb.domain.com => websites/bbb/

How could I write it?

My Gradle dependencies:

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('org.springframework.boot:spring-boot-starter-web-services')
compile('org.springframework.boot:spring-boot-starter-websocket')
runtime('org.postgresql:postgresql')
testCompile('org.springframework.boot:spring-boot-starter-test')

Thanks very much!

First update

I researched Spring a little deeper. And now I think a new HandlerMapping might be a better choice. So I want to rewrite the DefaultAnnotationHandlerMapping .

It's a class of package spring-webmvc , and defined in DispatcherServlet.properties as follows:

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

I can't change the DispatcherServlet.properties directly. So if I want to replace the class with my class, how could I do that?

I used a lot of spring-boot-starter instead of XML to define my project.

I tried to define the org.springframework.web.servlet.HandlerMapping in application.properties but failed.

Upvotes: 0

Views: 610

Answers (1)

mjlowky
mjlowky

Reputation: 1213

You can intercept the request and get the subdomain and then forward it to your desired path.

You can either implement a HandlerInterceptor or extend HandlerInterceptorAdapter for this purpose. Here is an example that gets the subdomain and forwards:

@Component
public class DomainHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, 
                             HttpServletResponse response, Object o) throws Exception {
        String subDomain = request.getServerName().split("\\.")[0];
        if (request.getAttribute("domainHandled") != null) {
            request.setAttribute("domainHandled", true);
            request.getRequestDispatcher("/websites/" + subDomain)
                    .forward(request, response);
            System.out.println(request.getRequestURL().toString());
            return false;
        }

        return true;
    }
}

Add the DomainInterceptor to the interceptor registry:

@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

    @Autowired 
    HandlerInterceptor domainHandlerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(domainHandlerInterceptor);
    }
}

Upvotes: 2

Related Questions