摘要 spring-boot整合web为啥能有这么多问题,好几天都是崩溃的。本文我就一个问题一个问题的交代,而且给出个人解决方案。解决方案未必是通用的,我仍是建议你们边跟代码边猜想,找到解决途径。最坑的就是百度那么多烂文章,耗费时间不解决问题。html
问题1: Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 不能正常跳转到jsp文件.java
问题定位:git
我走了下Dispatcher、AbstractView、JstlView这三个类。发现有一个参数一直是异常的:_contextHandlergithub
若是正常它应该是咱们项目信息:web
o.m.j.p.JettyWebAppContext{/es-web,file:/D:/材料/源码/zhangkaitao/123/es-master/web/src/main/webapp/},file:/D://es-master/web/src/main/webapp/spring
而在个人项目里,它是这个数据:springboot
o.s.b.c.e.j.JettyEmbeddedWebAppContext@527d5e48{/,file:///C:/Users/user/AppData/Local/Temp/jetty-docbase.4093955487572732783.8080/,AVAILABLE} 很显然,这个数据应该是配合错误的,这个类JettyEmbeddedWebAppContext是springboot里面的。打开它的父类,发现本身真的是太浅薄了,原来这个类也是能够配置不少信息的。这个参数太底层了,咱们没法直接操做,那么jetty给了咱们的配置工厂是AbstractEmbeddedServletContainerFactory,经过它可以解决。 想了半天如何添加,也疑惑为何项目根目录是这个c:文件夹,后来我将MyApplication里面的pplication.sources(MyApplication.class) 改为pplication.sources(this.getClass());就好使了。这一点必定跟加载机制有关系,深刻我不清楚。app
问题解决:webapp
@SpringBootApplication(exclude = PersistenceExceptionTranslationAutoConfiguration.class) @EnableConfigurationProperties @ComponentScan("com.framework.demo") public class MyApplication extends SpringBootServletInitializer { protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(this.getClass()); } public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
问题2:不要直接的运行MyApplication文件。 虽然网上一大堆直接运行MyApplication可以顺利的访问到项目资源,但是我直接运行确实找不到jsp页面的。因此这里建议用spring-boot的插件运行(mvn的spring-boot:run启动)。jsp
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.framework.demo.web.MyApplication</mainClass> <addResources>true</addResources> <layout>ZIP</layout> <classifier>exec</classifier> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
问题3:mvn install的时候测试类、文档类会出现问题
这个问题虽然最好找到解决方案,可是若是你没有时间,很着急,那么使用如下命令暂时绕过也是不过的选择。
install -D maven.javadoc.skip=true -D maven.test.skip=true
问题4:打包出错 repackage failed: Source must refer to an existing file sprinboot的打包是二次打包,必须是在已有包的基础上才可以打包成功(war、jar)
spring-boot:run命令须要有正确的依赖关系才能启动,若是使用spring-boot打包确定会找不到model之间的依赖关系。因此配置要改下。
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.framework.demo.web.MyApplication</mainClass> <addResources>true</addResources> <layout>ZIP</layout> //把原来的包install到本地私服中,若是不配置放入私服中的是springboot形式的包,结构彻底不一样,不一样model之间的依赖关系将被破坏。 <classifier>exec</classifier> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
问题五、spring-boot打包
spring-boot:repackage是二次打包命令,须要咱们事先打包好war。
spring-boot 之因此可以在程序打完包以后直接就可以运行,是由于它是将咱们项目包包裹在了本身的运行包中,进行了二次打包,深刻的有待接下来的研究。下面给出maven 的war包打包插件,注意下,若是项目中没有了web.xml,必定要将failOnMissingWebXml加上。
<plugin> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <webappDirectory>${project.build.directory}/${module.war.name}.war</webappDirectory> <warSourceDirectory>src/main/webapp</warSourceDirectory> <webResources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> <filtering>true</filtering> <targetPath>WEB-INF/classes/META-INF</targetPath> </resource> <resource> <directory>src/main/webapp/WEB-INF</directory> <filtering>true</filtering> <targetPath>WEB-INF</targetPath> <includes> <include>log4j.xml</include> </includes> </resource> </webResources> <resourceEncoding>UTF-8</resourceEncoding> </configuration> <executions> <execution> <id>default-war</id> <phase>package</phase> <goals> <goal>war</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.framework.demo.web.MyApplication</mainClass> <addResources>true</addResources> <layout>ZIP</layout> <classifier>exec</classifier> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
问题:静态文件访问不到
网上好多文章有点儿忽悠人的成分,能不能说清楚类路径先,而后在说spring-boot下面的默认资源路径在哪里放置,害得我看到页面正常访问的那一刻心里是崩溃的。spring-boot有五个默认的静态资源放置路径:
一、locations=[ServletContext resource [/],
二、class path resource [META-INF/resources/],
三、class path resource [resources/],
四、class path resource [static/],
五、class path resource [public/]
请各位注意,这块和咱们平时配置是不一样的。这里面说的是类路径,也就是说咱们平时java文件编译成class文件那个目录下。而webapp下面springboot是不会去找的。另外,一些文字说这样添加路径,classpath:WEB-INF/,这种提示很容易让人误解是和咱们以前的配置习惯一致,贻害不浅!!配置的时候必定要记得是类路径,不是咱们以前的webapp路径下!
欢迎来个人公众号:hyssop的后花园
参考文献 https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples http://docs.spring.io/spring-boot/docs/current/maven-plugin/index.html