这是自己昨天帮朋友处理问题遇到的一个问题,由于他使用了springBoot的web项目,视图模板采用的是thymeleaf。 因为模板解析出错了,所以我打算不用thymleaf模板(主要我也是有个私心,想验证自己学过的知识。不过最终还是采用了直接解决问题的方式。),直接使用springMvc的拦截返回,因此遇到了这样的一些问题。一是由于知识不到位,二是实践经验不足。
先看看过程吧:
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
org.springframework.boot
spring-boot-starter-web
依赖很简单明确,我就要用springBoot的web项目!因为通过查看它的依赖关系,我们是可以知道,web实际上是要依赖webmvc的。 因此符合我们的要求。
代码结构也简单粗暴:
package com.automannn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author [email protected]
* @time 2018/10/21 23:28
*/
@SpringBootApplication
@Controller
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
@RequestMapping("/getview")
public String getView(){
return "/view/test.html";
}
}
需求很明确,我要通过controller返回一个视图,该试图就是/view/test.html。 考虑到我并没有配置视图分发的前后缀,所以我采用了这种方式。测试:
发现出现了404错误。 怎么回事呢??
上网资料查,如下:
大牛的地址在:这里
所以,这里说明了两个问题: 就算我们什么都不配置,它的视图分发也应该由InternalResourceViewResolver完成才对,况且我用的版本源码变成如下:
由于它的default值都是空字符串。 所以这里有两种方式,都应该生效。第一,不配置mvc的前后缀,直接返回前后缀; 第二,配置mvc的前后缀,用视图的名称表示该资源。 但是这两种方式我都尝试过,不行!!!
经过很长时间的思考与查资料, 终于知道了原来内置tomcat与tomcat在这个方面是有一些区别的。 这也是springBoot不推荐jsp模板的原因好像。
看一下内置tomcat编译后的结构:
因此找到了问题,那么就试着解决一下。
首先,将spring-boot的tomcat依赖剔除。
这个时候运行,可以发现:
并没有启动新的线程,主线程执行完毕,程序退出。 是我们想要的效果。
接着开始配置tomcat容器。 但是 突然发现,这样的话,基本springBoot的上下文如何装配进tomcat容器,又是一个非常大的挑战。 因此换了一种思路。相当于ssm框架的思路,但是应该也可以通过特殊的方法,直接将tomcat容器与springBoot关联,逻辑上没毛病嘿嘿嘿。
思路断了,就只好换一种思路,因为默认装配的InternalResourceResolver实际上是针对jsp视图模板的,但是springBoot对jsp支持有限。 那么到底是怎么个区别呢???
原来啊,jsp的视图它的根路径,也就是mvc啥都不配的情况下,位于springBoot项目的src/main/weapp下!!!! 在这里也遇到了算是纠正自己思维误区的一个问题:
对于配置文件来说,如xxx.properties:
它并不认resources的文件夹名称本身,在这种状态下,这个文件夹只充当用于编译后的跳板。用于绑定到编译路径,并能通过classpath://得到。这是ide的工作,不是框架的工作。 经过编译后,它构成如下:
也就是说,我们完全可以建一个其它的文件夹然后将它放进去,也可以达到要求。 但是这个application.properties有些特殊,应该不是属于这种情况。
对于框架的配置文件来说,它只认文件夹的名字本身。 如resources/templates; src/main/webapp等情况。 这种情况下尽管编译后的路径下不包含该文件,任然是生效的。 这是框架的工作,而非ide的工作。
而这个恰恰也是这个问题的关键。(之所以会产生这种思维误区,是因为以前直接使用tomcat容器,以及集成ssm的时候留下的观念,还有就是太过于依赖ide的缘故)。
通过搜索springBoot返回jsp视图,不难发现,原来springBoot的对jsp的根路径的支持在src/main/webapp下。 因此赶紧尝试:
修改结构及其编译结构如下:
运行测试:
给它加上mvc配置的实验:
运行测试:
完全ok!
最后,记录一下thymeleaf错误的处理: