如何重写子域到路径?
示例:
最好是(反向文件夹):
请求foo。酒吧实例com应该在/src/main/resources/static/bar/foo/index中提供一个文件。html。
对于Apache2,它是由mod_rewrite完成的。我发现留档重写与Tomcat 8但问题是在哪里把这个文件使用Spring启动?
使现代化
我尝试使用UrlRewriteFilter,但似乎不可能使用正则表达式替换在域路径中定义规则。
这是我的配置:
Maven依赖:
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.3</version>
</dependency>
Spring Java配置以注册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;
}
}
urlrewrite.xml /src/main/webapp/WEB-INF
<?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>
对于这个硬编码域,它可以工作,但它应该适用于像这样的每个子域。
解决此问题的另一种方法是:在Controller中执行此操作。这在我看来比过滤器更好,因为:
/subdomain2path
方法与前面的答案相同。
这是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<String> 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");
}
}
}
域类与前面的答案相同:
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("\\.", "/") + "/";
}
}
您可以使用Backreferences
来使用在
<condition name="host" operator="equal">(*).(*).example.com</condition>
<from>^(.*)</from>
<to type="redirect">example.com/%1/%2</to>
当然,您必须调整上面的条件规则以停止急切匹配。
这里有更多-http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/4.0/index.html#condition
创建自己的过滤器。
此过滤器应:
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("\\.", "/") + "/";
}
}
你需要一个能捕捉一切的控制器
@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");
}
}
}
我不确定是否有必要重写HttpServletquiestWrapper
中的其他方法。这就是发表评论的原因。
此外,您还必须处理文件交付的案例(不存在,…)。
如何配置应用程序,使每个客户端都有其上下文? 例子: 主要 客户1。domain.com 客户1 域名。com/Login-- 我当前的应用程序使用子域的配置,因为springboot本身标识它在不同的上下文中,但是我不明白如何通过路径来做到这一点
我有时会在pom中看到以下声明。xml。。。 如您所见,sping-boo-starter-web被声明为tomcat-embed-jasper。 是不是sping-boo-starter-web已经有一个嵌入式tomcat了?为什么一些开发人员仍然声明tomcat-embed-jasper以及boot-starter-web?还是有什么原因?
我正在尝试将文件的绝对值传递给类路径的read函数。 如果我将绝对路径与类路径一起传递,它就会很好地工作。但当我传递嵌入式表达式时,它不起作用 我的代码如下 给定url appServer给定参数creationMethod=“swagger_first”和路径“/integration/rest/rad” 和头X-CSRF-TOKEN=csrfToken*cookie JSESSIONID=JS
当我试图使用ModelMapper将嵌套的java对象转换为嵌套的DTO时,我遇到了一个问题。在父DTO对象中,子DTO为null。以下是代码片段。 实体类: DTO的课程: 这是映射器代码: 输出: 输出用户DTO:UserDTO[名称=xyz,地址=null,产品=null] 在这里,我想将用户实体转换为UserDTO-dto。我得到了地址和产品DTO的空值。我在这里到底缺少什么?有人知道吗?
如何使用用户指定的架构将dataframe转换为Avro格式?
问题内容: 我在ttf文件中有一种字体,想要生成文本转换为路径的SVG。我不需要图像(因此使用imagettftext或Image Magick字体渲染功能是不够的),我需要可以放大和缩小的形状,我想丢失有关所用字体的信息,并且不想在其中引用它SVG文件(因此此处不能使用字体声明)。可能吗? 问题答案: 我创建了自己的类来处理SVG字体文件并将文本转换为字形。使用示例: 结果示例: 我班的代码: