gpt4 book ai didi

java - 如何使用嵌入式 Tomcat 8 和 Spring 引导将子域转换为路径

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:38:26 26 4
gpt4 key购买 nike

如何将子域重写为路径?

例子:

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

或者更好的是(反向文件夹):

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

请求 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>

用于注册 Servlet 过滤器的 Spring Java Config:

@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>

对于这个硬编码域,它可以工作,但它应该适用于像这样的每个子域。

最佳答案

创建您自己的过滤器。

这个过滤器应该:

  • 检查您是否必须重写您的请求
  • 如果是,重写 URL 和 URI
  • 转发请求
  • 它再次通过相同的过滤器,但第一次检查会传递 false
  • 不要忘记并小心调用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() {
}
}

这是域类:

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("\\.", "/") + "/";
}
}

你需要一个能捕捉一切的 Controller

@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 中的其他方法。这就是发表评论的原因。

您还必须处理文件传送的情况(不存在,...)。

关于java - 如何使用嵌入式 Tomcat 8 和 Spring 引导将子域转换为路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27318439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com