application.properties中,我只对 thymeleaf进行了配置 因为我发现freemarker的配置并没有被获取到。
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.checkTemplateLocation=false
spring.thymeleaf.suffix=.html
接着创建一个配置类 MvcConfig 继承 WebMvcConfigurerAdapter:
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@Configuration
@EnableAutoConfiguration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Bean
public FreeMarkerViewResolver freeMarkerViewResolver() {
MyFreeMarkerViewResolver resolver = new MyFreeMarkerViewResolver();
resolver.setPrefix(null);
resolver.setSuffix(".ftl");
resolver.setContentType("text/html; charset=UTF-8");
resolver.setRequestContextAttribute("request");
resolver.setExposeContextBeansAsAttributes(true);
resolver.setExposeRequestAttributes(true);
resolver.setExposeSessionAttributes(true);
resolver.setOrder(1);
return resolver;
}
}
其中用到了一个MyFreeMarkerViewResolver,这个类继承了FreeMarkerViewResolver 并重写了其中的loadView 方法,这个方法去freemarker的模板路径下找对应的ftl文件如果没找到对应文件则返回null(原因后面说),代码如下:
import java.io.IOException;
import java.util.Locale;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
public class MyFreeMarkerViewResolver extends FreeMarkerViewResolver {
// 由于我的freemarker 配置无法被加载所以我才写死的正确方法是 利用@Value注解获取
private String prefix = "classpath:/templates/“;
private String suffix = ".ftl";
@Override
protected org.springframework.web.servlet.View loadView(final String viewName, final Locale locale)
throws Exception {
String resourceName = prefix + viewName + suffix;
try {
this.getApplicationContext().getResource(resourceName).getInputStream();
} catch (final IOException e) {
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("视图名:" + resourceName + "不存在!");
} else {
logger.debug("视图名:" + resourceName + "不存在!");
}
}
return null;
}
return super.loadView(viewName, locale);
}
}
到这里就基本解决了SpringBoot只加载一个模板引擎的问题,下面说一说为什么要重写 FreeMarkerViewResolver 的 loadView()方法
在前端控制器DispatcherServlet中的viewResolvers保存的都是ViewResolver的实现类的对象,有一个resolveViewName() 方法会 遍历 viewResolvers,如果遇到 null则寻找下一个viewResolver,如果viewResolver!=null则使用它:
1. protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
2. HttpServletRequest request) throws Exception {
3.
4. for (ViewResolver viewResolver : this.viewResolvers) {
5. View view = viewResolver.resolveViewName(viewName, locale);
6. if (view != null) {
7. return view;
8. }
9. }
10. return null;
11. }
如果在完成以上配置后成功装配两个模板引擎但是遇到静态 文件加载失败的问题请参考我的另一片博客:https://blog.youkuaiyun.com/weixin_42851893/article/details/87977523