创建您自己的过滤器。
该过滤器应:
- 检查是否必须重写您的请求
- 如果是,则重写URL和URI
- 转发请求
- 它再次通过相同的过滤器到达,但先检查将传递错误
- 不要忘记,要小心打电话
chain.doFilter
转发不会更改浏览器中的任何URL。只需发送文件内容即可。
遵循代码可能是此类过滤器的实现。这不是任何干净的代码。只是快速而肮脏的工作代码:
@Componentpublic 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("\.", "/") + "/"; }}而且您需要一个能够捕获所有内容的控制器
@RestControllerpublic 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。这就是发表评论的原因。
另外,您还必须处理文件传递的情况(不存在,…)。



