How to convert a subdomain to a path with Embedded Tomcat 8 and Spring boot

前端 未结 4 1421
执念已碎
执念已碎 2021-02-06 04:57

How to rewrite subdomains to paths?

Example:

  • foo.bar .example.com --> example.com /foo/bar

Or better woul

4条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-06 05:17

    Another way to solve this issue: Do it in Controller itself. This is in my opinion better way than with filter because:

    • filter catches every request. Here you can better controll which requests should be delivered with 'subdomain pattern'. As example I've choosen /subdomain2path.
    • You don't have to change/wrap URI/URLs and forward via filter chain again.
    • All logic is in this controller

    Methods getSubdomain and reverseDomain are same as in answer before.

    This is the impl:

    @RestController
    @RequestMapping("/subdomain2path")
    public class Subdomain2PathController {
    
        @RequestMapping("/")
        public FileSystemResource deliver(final HttpServletRequest request) {
            final Domain subdomain = getSubdomain(request.getServerName());
    
            String file = "/";
            if (subdomain.hasSubdomain()) {
                file = subdomain.getSubdomainAsPath();
            }
    
            return new FileSystemResource(getStaticFile(file));
        }
    
        private Domain getSubdomain(final String domain) {
            final String[] domainParts = domain.split("\\.");
            String mainDomain;
            String subDomain = null;
    
            final int dpLength = domainParts.length;
            if (dpLength > 2) {
                mainDomain = domainParts[dpLength - 2] + "." + domainParts[dpLength - 1];
    
                subDomain = reverseDomain(domainParts);
            } else {
                mainDomain = domain;
            }
    
            return new Domain(mainDomain, subDomain);
        }
    
        private String reverseDomain(final String[] domainParts) {
            final List subdomainList = Arrays.stream(domainParts, 0, domainParts.length - 2)//
                    .collect(Collectors.toList());
    
            Collections.reverse(subdomainList);
    
            return subdomainList.stream().collect(Collectors.joining("."));
        }
    
        private File getStaticFile(final String path) {
            try {
                // TODO handle correct
                return new File(Subdomain2PathController.class.getResource("/static/" + path + "/index.html").toURI());
            } catch (final Exception e) {
                throw new RuntimeException("not found");
            }
        }
    }
    

    Domain class is same as in answer before:

    public static class Domain {
        private final String maindomain;
        private final String subdomain;
    
        public Domain(final String maindomain, final String subdomain) {
            this.maindomain = maindomain;
            this.subdomain = subdomain;
        }
    
        public String getMaindomain() {
            return maindomain;
        }
    
        public String getSubdomain() {
            return subdomain;
        }
    
        public boolean hasSubdomain() {
            return subdomain != null;
        }
    
        public String getSubdomainAsPath() {
            return "/" + subdomain.replaceAll("\\.", "/") + "/";
        }
    }
    

提交回复
热议问题