Spring Boot中Freemarker多模板加载器回退功能失效问题
Freemarker MultiTemplateLoader 未触发回退加载问题
我在开发一个使用Freemarker作为模板引擎的Spring Boot项目,已配置MultiTemplateLoader从baselineUrl和dynamicUrl两个不同CDN地址加载模板,预期逻辑是当baselineUrl中找不到模板时自动回退到dynamicUrl加载。但实际运行时,baselineUrl返回403错误后,程序并未尝试从dynamicUrl加载,而该模板实际存在于dynamicUrl中。已验证两个URL均正确且可访问,也尝试清除缓存排除缓存问题,但回退功能仍未生效。
配置类代码
@Slf4j @Configuration @ConfigurationProperties("email") @Data public class FtlConfiguration { // https://dynamic/bhnpay-static/notification-template/ftl private String baselineUrl; // https://baseline/bhnpay-static/notification-template/ftl private String dynamicUrl; private long retentionTimeMillis; @Bean("emailConfiguration") public freemarker.template.Configuration createFtlConfigBean() throws IOException { freemarker.template.Configuration cfg = new freemarker.template.Configuration( freemarker.template.Configuration.VERSION_2_3_31); cfg.setDefaultEncoding(NotificationConstants.UTF_8); cfg.setLogTemplateExceptions(false); cfg.setWrapUncheckedExceptions(true); cfg.setFallbackOnNullLoopVariable(false); cfg.setLocalizedLookup(false); List<TemplateLoader> loaders = new ArrayList<>(); // CloudTemplateLoader is just a wrapper on UrlTemplateLoader loaders.add(new CloudTemplateLoader(new URL(baselineUrl))); loaders.add(new CloudTemplateLoader(new URL(dynamicUrl))); cfg.setTemplateLoader( new MultiTemplateLoader(loaders.toArray(new TemplateLoader[0]))); cfg.setCacheStorage(new MruCacheStorage(5000, Integer.MAX_VALUE)); cfg.setTemplateUpdateDelayMilliseconds(retentionTimeMillis); return cfg; } }
模板加载处理器代码
@Component @Slf4j public class FtlTemplateHandler { private final Configuration configuration; @Autowired public FtlTemplateHandler(@Qualifier("emailConfiguration") Configuration configuration) { this.configuration = configuration; } public String getTemplateAsHtml(String emailTemplateUrl) { try { Template template = configuration.getTemplate(emailTemplateUrl); // Process the template } catch (IOException e) { try { log.info("removing template from cache {}", emailTemplateUrl); configuration.removeTemplateFromCache(emailTemplateUrl); Thread.sleep(10000); } catch (IOException | InterruptedException ex) { // process exception } } } }
CloudTemplateLoader实现代码
@Slf4j public class CloudTemplateLoader extends URLTemplateLoader { private URL root; public CloudTemplateLoader(URL root) { super(); this.root = root; } public URL getRoot() { return root; } public void setRoot(URL root) { this.root = root; } @Override protected URL getURL(String template) { try { return new URL(root, template); } catch (MalformedURLException e) { log.error("Error while loading templates from cloud."); } return null; } }
错误日志
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://baseline/bhnpay-static/notification-template/ftl/en-US/b9b09aa4-fd39-4812-924e-1fe7f6d4ed51.ftl at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.base/sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:3256) at java.base/java.net.HttpURLConnection.getHeaderFieldDate(HttpURLConnection.java:601) at java.base/java.net.URLConnection.getLastModified(URLConnection.java:567) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getLastModified(HttpsURLConnectionImpl.java:392) at freemarker.cache.URLTemplateSource.lastModified(URLTemplateSource.java:94) at freemarker.cache.URLTemplateLoader.getLastModified(URLTemplateLoader.java:50) at freemarker.cache.MultiTemplateLoader$MultiSource.getLastModified(MultiTemplateLoader.java:142) at freemarker.cache.MultiTemplateLoader.getLastModified(MultiTemplateLoader.java:99) at freemarker.cache.TemplateCache.getTemplateInternal(TemplateCache.java:439)
内容的提问来源于stack exchange,提问作者Singhai
相关产品推荐
相关产品推荐

