0

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.

zhy1378
  • 329
  • 1
  • 2
  • 7
  • Try writing some code then post it, so we can help you. We can't produce code for you – akuma8 Oct 05 '17 at 07:10
  • You can check reverse proxying (https://en.wikipedia.org/wiki/Reverse_proxy). It can distribute the request to spring request handlers based on the domains. – mjlowky Oct 05 '17 at 07:46

1 Answers1

2

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);
    }
}
mjlowky
  • 1,183
  • 12
  • 19
  • Thanks a lot! I should put it into HandlerExecutionChain then, I think. But I didn't find a way to disable the initialize of the bean HandlerInterceptorAdapter and replace it with DomainHandlerInterceptor. – zhy1378 Oct 05 '17 at 14:02
  • You don't need to disable anything. Just add the `DomainHandlerInterceptor` to your `InterceptorRegistry`. See the edited answer – mjlowky Oct 05 '17 at 14:20
  • I updated the question, could you please help me a little further? – zhy1378 Oct 07 '17 at 18:55