如何将子域重写为路径?
例:
或更好的是(反向文件夹):
请求 foo.bar .example.com应该将文件发送到/ src / main / resources / static / bar / foo /index.html中。
使用Apache2可以通过 mod_rewrite 完成。我找到了有关使用Tomcat 8重写的文档,但问题是使用Spring Boot将这些文件放在哪里?
更新资料
我尝试使用UrlRewriteFilter,但是似乎无法使用正则表达式替换在域路径中定义规则。
这是我的配置:
Maven依赖关系:
<dependency> <groupId>org.tuckey</groupId> <artifactId>urlrewritefilter</artifactId> <version>4.0.3</version> </dependency>
Spring Java Config注册Servlet过滤器:
@Configuration @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new UrlRewriteFilter()); registrationBean.addUrlPatterns("*"); registrationBean.addInitParameter("confReloadCheckInterval", "5"); registrationBean.addInitParameter("logLevel", "DEBUG"); return registrationBean; } }
*/ src / main / webapp / WEB-INF中的 *urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd"> <urlrewrite> <rule> <name>Translate</name> <condition name="host" operator="equal">foo.bar.example.com</condition> <from>^(.*)</from> <to type="redirect">example.com/bar/foo</to> </rule> </urlrewrite>
使用此 硬编码 域,它可以工作,但它应适用于 每个 子域,如下所示。
创建您自己的过滤器。
该过滤器应:
chain.doFilter
转发不会更改浏览器中的任何URL。只需发送文件内容即可。
遵循代码可能是此类过滤器的实现。这不是任何干净的代码。只是快速而肮脏的工作代码:
@Component public class SubdomainToReversePathFilter implements Filter { @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest req = (HttpServletRequest) request; final String requestURI = req.getRequestURI(); if (!requestURI.endsWith("/")) { chain.doFilter(request, response); } else { final String servername = req.getServerName(); final Domain domain = getDomain(servername); if (domain.hasSubdomain()) { final HttpServletRequestWrapper wrapped = wrapServerName(req, domain); wrapped.getRequestDispatcher(requestURI + domain.getSubdomainAsPath()).forward(wrapped, response); } else { chain.doFilter(request, response); } } } private Domain getDomain(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 HttpServletRequestWrapper wrapServerName(final HttpServletRequest req, final Domain domain) { return new HttpServletRequestWrapper(req) { @Override public String getServerName() { return domain.getMaindomain(); } // more changes? getRequesetURL()? ...? }; } private String reverseDomain(final String[] domainParts) { final List<String> subdomainList = Arrays.stream(domainParts, 0, domainParts.length - 2)// .collect(Collectors.toList()); Collections.reverse(subdomainList); return subdomainList.stream().collect(Collectors.joining(".")); } @Override public void init(final FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
这是Domain类:
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("\\.", "/") + "/"; } }
而且您需要一个能够捕获所有内容的控制器
@RestController public class CatchAllController { @RequestMapping("**") public FileSystemResource deliver(final HttpServletRequest request) { final String file = ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)); return new FileSystemResource(getStaticFile(file)); } private File getStaticFile(final String path) { try { // TODO handle correct return new File(CatchAllController.class.getResource("/static/" + path + "/index.html").toURI()); } catch (final Exception e) { throw new RuntimeException("not found"); } } }
我不确定是否有必要重写中的其他方法HttpServletRequestWrapper。这就是发表评论的原因。
HttpServletRequestWrapper
另外,您还必须处理文件传递的情况(不存在,…)。