spring 启动 Thymeleaf 相对 URL
spring boot Thymeleaf relative urls
我现在正在使用 spring boot 1.3 和 thymeleaf。
这是我的 thymeleaf 页面的一部分:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot and Thymeleaf demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="" th:src="@{/js/our.min.js}"></script>
</head>
<body>
</body>
</html>
如你所见,我的url就像
<script type="text/javascript" src="" th:src="@{/js/our.min.js}"></script>
当我的 jquery 和我的代码在同一台服务器上时,这很好用。
但是现在我的js会部署到CDN,并且会加版本,可能是这样的:
<script type="text/javascript" src="http://s1.cdn.xxx.com/s/js/our.min.js?v=3QxjsKtdfdfsx"></script>
如你所见,我们做了三件事。
首先:添加一个httpurl:http://s1.cdn.xxx.com/s/
,这个url可以从配置文件中读取。
其二:添加版本后缀v=3QxjsKtdfdfsx
第三次:全部合并
http://s1.cdn.xxx.com/s/ + /js/our.min.js + v=3QxjsKtdfdfsx
我想知道 spring boot 或 thymeleaf 是否提供这样的功能来做这些事情或功能。
谢谢。
据我所知,没有任何开箱即用的东西可以为您处理这种行为,但是编写自定义标签 (Thymeleaf Processor
) 来封装逻辑非常容易并使其在任何地方都易于使用。
刚才我不得不做基本相同的事情:
首先,创建一个简单的处理器,它只是一个 class 来处理您的自定义属性:
@Component
class CdnUrlProcessor extends AbstractStandardSingleAttributeModifierAttrProcessor{
@Autowired UrlService urlService
private final int HIGHEST_PRECEDENCE = Integer.MAX_VALUE
// Here we use a multi attribute matcher - we also link the processor to
// the CDN Dialect - which is just the namespace for the attributes
public CdnUrlProcessor(){
super( new MultipleAttributeMatcher( CdnDialect, ["src", "href"] ) )
}
// These are just boilerplate overrides
@Override protected String getTargetAttributeName(Arguments arguments, Element element, String attributeName) {
Attribute.getUnprefixedAttributeName(attributeName)
}
@Override protected ModificationType getModificationType(Arguments arguments, Element element, String attributeName, String newAttributeName) {
ModificationType.SUBSTITUTION
}
@Override protected boolean removeAttributeIfEmpty(Arguments arguments, Element element, String attributeName, String newAttributeName) {
false
}
@Override public int getPrecedence() {
HIGHEST_PRECEDENCE
}
// This is where the magic happens - you can put your logic to build
// the url in here, or you could autowire a service (I did, as I wanted
// the logic available outside of Thymeleaf
@Override protected String getTargetAttributeValue( Arguments arguments, Element element, String attributeName ){
urlService.generateCdnUrl( element.getAttributeValue(attributeName) )
}
}
然后你需要创建方言 - 正如上面代码注释中提到的,这只是一个 namespace/prefix 将用于分组和应用处理器:
@Component class CdnDialect extends AbstractDialect {
@Autowired CdnUrlProcessor cdnUrlProcessor
public CdnDialect() {
super()
}
public String getPrefix() {
"cdn"
}
@Override public Set<IProcessor> getProcessors() {
[ cdnUrlProcessor ] as Set
}
}
Thymeleaf 就是这样(尽管检查测试 - 您显然想为此添加测试,这很容易添加)。
然后您可以在带有自定义前缀的 HTML 模板中使用您的处理器,就像您使用 Thymeleaf "th" 属性一样:
<script type="text/javascript" src="" cdn:src="/js/our.min.js"></script>
(顺便说一下,上面的代码是从我的 Groovy 中复制的 - 所以如果你在 java 中,你将需要添加 return 关键字和分号)
我现在正在使用 spring boot 1.3 和 thymeleaf。
这是我的 thymeleaf 页面的一部分:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot and Thymeleaf demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="" th:src="@{/js/our.min.js}"></script>
</head>
<body>
</body>
</html>
如你所见,我的url就像
<script type="text/javascript" src="" th:src="@{/js/our.min.js}"></script>
当我的 jquery 和我的代码在同一台服务器上时,这很好用。
但是现在我的js会部署到CDN,并且会加版本,可能是这样的:
<script type="text/javascript" src="http://s1.cdn.xxx.com/s/js/our.min.js?v=3QxjsKtdfdfsx"></script>
如你所见,我们做了三件事。
首先:添加一个httpurl:http://s1.cdn.xxx.com/s/
,这个url可以从配置文件中读取。
其二:添加版本后缀v=3QxjsKtdfdfsx
第三次:全部合并
http://s1.cdn.xxx.com/s/ + /js/our.min.js + v=3QxjsKtdfdfsx
我想知道 spring boot 或 thymeleaf 是否提供这样的功能来做这些事情或功能。
谢谢。
据我所知,没有任何开箱即用的东西可以为您处理这种行为,但是编写自定义标签 (Thymeleaf Processor
) 来封装逻辑非常容易并使其在任何地方都易于使用。
刚才我不得不做基本相同的事情:
首先,创建一个简单的处理器,它只是一个 class 来处理您的自定义属性:
@Component
class CdnUrlProcessor extends AbstractStandardSingleAttributeModifierAttrProcessor{
@Autowired UrlService urlService
private final int HIGHEST_PRECEDENCE = Integer.MAX_VALUE
// Here we use a multi attribute matcher - we also link the processor to
// the CDN Dialect - which is just the namespace for the attributes
public CdnUrlProcessor(){
super( new MultipleAttributeMatcher( CdnDialect, ["src", "href"] ) )
}
// These are just boilerplate overrides
@Override protected String getTargetAttributeName(Arguments arguments, Element element, String attributeName) {
Attribute.getUnprefixedAttributeName(attributeName)
}
@Override protected ModificationType getModificationType(Arguments arguments, Element element, String attributeName, String newAttributeName) {
ModificationType.SUBSTITUTION
}
@Override protected boolean removeAttributeIfEmpty(Arguments arguments, Element element, String attributeName, String newAttributeName) {
false
}
@Override public int getPrecedence() {
HIGHEST_PRECEDENCE
}
// This is where the magic happens - you can put your logic to build
// the url in here, or you could autowire a service (I did, as I wanted
// the logic available outside of Thymeleaf
@Override protected String getTargetAttributeValue( Arguments arguments, Element element, String attributeName ){
urlService.generateCdnUrl( element.getAttributeValue(attributeName) )
}
}
然后你需要创建方言 - 正如上面代码注释中提到的,这只是一个 namespace/prefix 将用于分组和应用处理器:
@Component class CdnDialect extends AbstractDialect {
@Autowired CdnUrlProcessor cdnUrlProcessor
public CdnDialect() {
super()
}
public String getPrefix() {
"cdn"
}
@Override public Set<IProcessor> getProcessors() {
[ cdnUrlProcessor ] as Set
}
}
Thymeleaf 就是这样(尽管检查测试 - 您显然想为此添加测试,这很容易添加)。
然后您可以在带有自定义前缀的 HTML 模板中使用您的处理器,就像您使用 Thymeleaf "th" 属性一样:
<script type="text/javascript" src="" cdn:src="/js/our.min.js"></script>
(顺便说一下,上面的代码是从我的 Groovy 中复制的 - 所以如果你在 java 中,你将需要添加 return 关键字和分号)