细数Spring Boot 中容易中招的那些坑

本篇博文会不时整理总结更新Spring Boot 学习和开发中遇到的一些坑,并提供出解决方案,希望可以帮到不小心落入深坑的你。

0x00 No Beans of ‘XXXProperties’ type found

这里写图片描述

解决方案:
添加 @Component 注解实体类即可
这里写图片描述

0x01 Spring Boot Configuration Annotation Processor not found in classpath

这里写图片描述

解决方案:
添加如下依赖即可:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

更多详细信息参考:
https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor

0x02 No identifier specified for entity

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource
。。。
Caused by: org.hibernate.AnnotationException: No identifier specified for entity
这里写图片描述

解决方案:
这里有个可能令你痛不欲生的坑!
@Id 应该引用的是import javax.persistence.Id;
而不是import org.springframework.data.annotation.Id;
要不会引起no identifier specified for entity 这个错误

0x03 java.lang.ClassNotFoundException: javax.xml.bind.JAXBException

解决方案:http://blog.csdn.net/hadues/article/details/79188793

0x04 Unregistering JMX-exposed beans on shutdown

当我们在使用maven创建Spring Boot 项目,项目打包方式为war包的时候,经常会看到这样的错误日志:

2018-04-05 18:09:34.010  INFO 12300 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-04-05 18:09:34.039  INFO 12300 --- [           main] c.x.smartblog.SmartblogApplication       : Started SmartblogApplication in 3.484 seconds (JVM running for 5.865)
2018-04-05 18:09:34.043  INFO 12300 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2796aeae: startup date [Thu Apr 05 18:09:31 CST 2018]; root of context hierarchy
2018-04-05 18:09:34.045  INFO 12300 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

Process finished with exit code 0

解决方案一:
当然这个问题的解决方案很简单,你可以很轻松在网上找到这个解决方案
注释掉provided

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!--<scope>provided</scope>-->
        </dependency>

虽然问题解决呢,但是我内心还是很好奇的,一好奇为什么注释掉这个就可以修复这个bug, 二好奇为什么Intellij Idea 会默认创建一个启动不了的项目模板呢?
解决方案二:

直到后来我终于找到了解决方案

原因在于Application 运行时缺少一个容器container,

项目中为了打成war 包,引入了 依赖,该依赖默认scope 为provided,编译直接运行后,无法确定一个容器,项目无法启动。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

把provided改为 compile

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>compile</scope>
        </dependency>

一般这样就可以成功,但是你可能很神奇发现竟然还是运行失败,为什么呢?

因为生成的classes目录中没有更新,删除target目录下的所有数据重新运行即可。

这里写图片描述

总结,无论是Spring Boot 项目还是其他传统的web项目,当我们选择打包成war包后,一般需要手动部署到服务器上Tomcat或Jetty等Web容器来加载这个war包,所以使用Intellij Idea 就使用了provided

provided
provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。

如果还是不懂,请移步 Maven依赖中的scope详解

0x05 Spring Boot 2.0 返回JSP 页面404问题

针对这个问题,总结几点需要注意的地方
1. 注意配置文件application.properties

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

Tips: 这里应该是key 和value 通过= 的键值对形式,而不是

spring.mvc.view.prefix:/WEB-INF/jsp/
spring.mvc.view.suffix:.jsp

2.如果需要返回JSP页面,必须配置如下依赖项:

<!--- Web 模块必须添加 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--jsp页面使用jstl标签-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--Provided  start-->
        <!--War包部署到外部的Tomcat中已经包含了这些,
        所以需要添加以下依赖
        否则会和内嵌的Tomcat 容器发生冲突
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--用于编译jsp-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Provided  end-->

3.必须实现SpringBootServletInitializer 接口并且重写方法

@SpringBootApplication
public class SmartblogApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SmartblogApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SmartblogApplication.class);
    }
}

4.控制器不能用@RestController注解

@Controller
public class HomeController {


    @GetMapping(value = "/")
    public String home(){
        return "index";
    }
}

只能用@Controller 注解,不能用@RestController 注解
5. 必须手动创建 webapp/WEB-INF 文件夹
创建文件夹目录如下图所示,且文件夹名称要和application.properties中配置的要保持一致
这里写图片描述
6.不能使用Run As Java Application 类型

在Intellij Idea IDE中只能通过外部的Tomcat 来启动War 包,不能使用Run As Java Application 类型方式启动War 包。

换句话说就是如果用JSP页面,则不能用Jar 的方式使用内嵌的Tomcat,只能通过外部的Tomcat加载War 包方式来启动项目,否则会出现页面找不到问题。
详情请移步:https://www.jianshu.com/p/c544e9a9e96f

0x06 Spring Boot 2.0 引入的CSS,jS 失效

今天在使用Spring Boot 2.0 搭建一个项目引入JS和CSS 文件时,发现引入的CSS 和JS文件完全失效,F12 看了下发现CSS,jS 被拦截了,只有文件名没有文件内容。整个页面都是乱七八糟。

百度搜索和谷歌发现这类问题大多数的解决方案都说需要继承一个神马类那么麻烦地来解决。

真心觉得麻烦,于是乎,最终找到了最优解决方案,

其实Spring Boot 2.x 版本针对这个问题有最优解决方案,直接修改application.properties 文件即可

spring.mvc.static-path-pattern=/static/**

详情请移步:真正解决方案:Spring Boot 2.0 引入JS,CSS 失效问题

猜你喜欢

转载自blog.csdn.net/hadues/article/details/79334355
今日推荐