springboot 入门

1 Spring boot helloworld
1.1 介绍
随着 structs2 出现的漏洞的逐渐显现,开发者对 spring 的关注度开始越来越重。不断对其进行改进和优化,
以前 spring 开发需要配置一大堆的 xml,后来加入了 annotaion, 使得 xml 配置简化了
很多,当然还是有些配置需要使用 xml,比如申明 component scan 等。
 spring boot,的出现主要是为了降低 spring 的入门,使得开发新手可以以最
快的速度基于spring开发程序。
那么如何写运用springboot和maven来写出我们的第一个程序(demo)Hello world 呢?
步骤如下:
(1)新建一个 Maven Java 工程
(2)在 pom.xml 文件中添加 Spring Boot Maven 依赖
(3)编写启动类
(4)运行程序
1.2 Hello 之 New
这个步骤很简单,相比大家都会,小编在此为了文档的完整性,稍作简单说明:
首先使用 IDE(Eclipse,MyEclipse)工具新建一个 Maven 工程,可以是 Maven Java Project,也可以
是 Maven Web Project,随便取一个工程名称。我使用的是 STS,工程名是 spring-boot-hello1。
1.3 Hello 之 Maven
第二步, 在 pom.xml中引入 spring-boot-start-parent,spring官方的解释叫什么 stater poms,
它可以提供 dependency management,也就是说依赖管理,引入以后在申明其它 dependency 的时候就
不需要 version 了,后面可以看到。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
1.4 Hello 之 maven web
第三步,因为我们开发的是 web 工程,所以需要在 pom.xml 中引入 spring-boot-starter-
web,spring 官方解释说 spring-boot-start-web 包含了 spring webmvc 和 tomcat 等 web 开发的特性。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
3 / 42
</dependency>
</dependencies>
1.5 Hello 之 Maven Run Application
如果我们要直接 Main 启动 spring,那么以下 plugin 必须要添加,否则是无法启动的。如果使
用 maven 的 spring-boot:run 的话是不需要此配置的。 (我在测试的时候,如果不配置下面的 plugin
也是直接在 Main 中运行的。 )
< build >
< plugins >
< plugin >
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-maven-plugin </ artifactId >
</ plugin >
</ plugins >
</ build >
1.6 Hello 之 coding
第四步,真正的程序开始啦,我们需要一个启动类,然后在启动类申明让 spring boot 自动给
我们配置 spring 需要的配置,比如:@SpringBootApplication,为了可以尽快让程序跑起来,我们简
单写一个通过浏览器访问 hello world 字样的例子:
@RestController
@SpringBootApplication
public class  App {
@RequestMapping ( "/" )
public String hello(){
return  "Hello world!" ;
}
4 / 42
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
其中@SpringBootApplication 申明让 spring boot 自动给程序进行必要的配置,等价于以默认属性使
用@Configuration,@EnableAutoConfiguration 和@ComponentScan
@RestController 返回 json 字符串的数据,直接可以编写 RESTFul 的接口;
1.7 Hello 之 Run
第五步, 就是运行我们的 Application 了, 我们先介绍第一种运行方式。 第一种方式特别简单:
右键 Run As -> Java Application。之后打开浏览器输入地址:http://127.0.0.1:8080/ 就可以看到 Hello
world!了。 第二种方式右键 project – Run as – Maven build – 在 Goals 里输入 spring-boot:run ,
然后 Apply,最后点击 Run。
1.8 Hello 之 Error
顺利的情况下当然是皆大欢喜了,但是程序吧往往会给你开个小玩笑。那么我们要注意什么呢?
主要是 jdk 的版本之类的,请看官方说明:
2 Spring boot  返回 json  数据
在做如下操作之前,我们对之前的 Hello 进行简单的修改,我们新建一个包 com.kfit.test.web 然后
新建一个类 HelloControoler, 然后修改 App.java 类,主要是的这个类就是一个单纯的启动类。
主要代码如下:
App.java
iackage com.kfit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*/
5 / 42
//其中@SpringBootApplication 申明让 spring boot 自动给程序进行必要的配置,等价于以默认属性使用
//@Configuration,@EnableAutoConfiguration 和@ComponentScan
//@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
com.kfit.test.web.HelloController :
package com.kfit.test.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController// 标记为:restful
public class HelloController {
@RequestMapping("/")
public String hello(){
return"Hello world!";
}
}
运行代码和之前是一样的效果的。
我们在编写接口的时候,时常会有需求返回 json 数据,那么在 spring boot 应该怎么操作呢?主要是
在 class 中加入注解@RestController,。
返回 回 JSON  之步骤:
(1)编写一个实体类 Demo
(2)编写 DemoController;
(3)在 DemoController 加上@RestController 和@RequestMapping 注解;
(4)测试
具体代码如下:
com.kfit.test.bean.Demo :
package com.kfit.test.bean;
/**
* 测试实体类.
* @author Administrator
*
*/
public class Demo {
6 / 42
private longid;//主键.
private String name;//测试名称.
public long getId() {
returnid;
}
public void setId(longid) {
this.id = id;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
}
com.kfit.test.web.DemoController:
package com.kfit.test.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.kfit.test.bean.Demo;
/**
* 测试.
* @author Administrator
*
*/
@RestController
@RequestMapping("/demo")
public class DemoController {
/**
* 返回 demo 数据:
* 请求地址:http://127.0.0.1:8080/demo/getDemo
* @return
*/
@RequestMapping("/getDemo")
public Demo getDemo(){
7 / 42
Demo demo = new Demo();
demo.setId(1);
demo.setName("Angel");
return demo;
}
}
那么在浏览器访问地址:http://127.0.0.1:8080/demo/getDemo 返回如下数据:
{
i id d: 1,
n n ame: "Angel"
}
是不是很神奇呢,其实 Spring Boot 也是引用了 JSON 解析包 Jackson,那么自然我们就可以在 Demo 对
象上使用 Jackson 提供的 json 属性的注解,对时间进行格式化,对一些字段进行忽略等等。
Spring boot 热部署
在编写代码的时候,你会发现我们只是简单把打印信息改变了下,就需要重新部署,如果是这样的编
码方式,那么我们估计一天下来之后就真的是打几个 Hello World 之后就下班了。那么如何解决热部
署的问题呢?那就是 springloaded,加入如下配置:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- 配置热部署 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
如果是使用 spring-boot:run 的话,那么到此配置结束,现在你就可以体验 coding… coding 的爽了。
如果使用的 run as – java application 的话,那么还需要做一些处理哦:
把 spring-loader-1.2.4.RELEASE.jar 下载下来,放到项目的 lib 目录中,然后把 IDEA 的 run 参数里
VM 参数设置为:
-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify
然后启动就可以了,这样在 run as 的时候,也能进行热部署了。
8 / 42
3 Spring boot  使用 其他 json  转换框架
个人使用比较习惯的 json 框架是 fastjson,所以 spring boot 默认的 json 使用起来就很陌生了,所
以很自然我就想我能不能使用 fastjson 进行 json 解析呢?
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.15</version>
</dependencies>
这里要说下很重要的话,官方文档说的 1.2.10 以后,会有两个方法支持 HttpMessageconvert,一
个是 FastJsonHttpMessageConverter, 支持 4.2 以下的版本, 一个是 FastJsonHttpMessageConverter4
支持 4.2 以上的版本,具体有什么区别暂时没有深入研究。这里也就是说:低版本的就不支持了,所
以这里最低要求就是 1.2.10+。
配置 fastjon
支持两种方法:
第一种方法:
(1)启动类继承 extends WebMvcConfigurerAdapter
(2)覆盖方法 configureMessageConverters
第二种方法:
(1)在 App.java 启动类中,注入 Bean : HttpMessageConverters
具体代码如下:
代码:App.java
i i mport java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
//如果想集成其他的json框架需要继承WebMvcConfigurerAdapter,并重写
configureMessageConverters
@SpringBootApplication
public  class App  extends WebMvcConfigurerAdapter {
// 第一种方式,重写configureMessageConverters,并将FastJsonConverter设置到系统中
@Override
public  void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter =  new FastJsonHttpMessageConverter();
converter.setFeatures(SerializerFeature. PrettyFormat );
converters.add(converter);
super.configureMessageConverters(converters);
}
9 / 42
// 第二种方法:注入beanHttpMessageConverters
/*
* @Bean public HttpMessageConverters faMessageConverters(){
* return new HttpMessageConverters(new FastJsonHttpMessageConverter()); }
*/
public  static  void main(String[] args) {
SpringApplication. run (App. class, args);
}
}
4 Spring boot  全局 异常捕捉
在一个项目中的异常我们我们都会统一进行处理的,那么如何进行统一进行处理呢?
新建一个类 GlobalDefaultExceptionHandler,
在 class 注解上@ControllerAdvice,
@ @C C ONTROLLER A A DVICE : :  即把 @C ONTROLLER A A DVICE 注解内部使用 @E XCEPTION H H ANDLER 、 、  @I NIT B B INDER 、 、  @M ODEL A A TTRIBUTE E
注解的方法应用到所有的 @R EQUEST M M APPING 注解的方法。 非常简单, 不过只有当使用 @E XCEPTION H H ANDLER
最有用,另外两个用处不大。
在方法上注解上@ExceptionHandler(value = Exception.class),具体代码如下
package com.kfit.base.exception;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
publicclass GlobalDefaultExceptionHandler {
@ExceptionHandler(value = Exception.class)
publicvoid defaultErrorHandler(HttpServletRequest req, Exception e) {
// // If the exception is annotated with @ResponseStatus rethrow it and let
// // the framework handle it - like the OrderNotFoundException example
// // at the start of this post.
// // AnnotationUtils is a Spring Framework utility class.
// if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
// throw e;
//
// // Otherwise setup and send the user to a default error-view.
// ModelAndView mav = new ModelAndView();
10 / 42
// mav.addObject("exception", e);
// mav.addObject("url", req.getRequestURL());
// mav.setViewName(DEFAULT_ERROR_VIEW);
// return mav;
//打印异常信息:
e.printStackTrace();
System.out.println("GlobalDefaultExceptionHandler.defaultErrorHandler()");
/*
* 返回 json 数据或者 String 数据:
* 那么需要在方法上加上注解:@ResponseBody
* 添加 return 即可。
*/
/*
* 返回视图:
* 定义一个 ModelAndView 即可,
* 然后 return;
* 定义视图文件(比如:error.html,error.ftl,error.jsp);
*
*/
}
}
com.kfit.test.web.DemoController 加入方法:
@RequestMapping("/zeroException")
publicint zeroException(){
return 100/0;
}
访问:http://127.0.0.1:8080/zeroException 这个方法肯定是抛出异常的,那么在控制台就可以看到我们全局捕捉
的异常信息了
5 Spring boot JPA  连接 数据库
在任何一个平台都逃离不了数据库的操作,那么在 spring boot 中怎么接入数据库呢?
很简单,我们需要在 application.properties 进行配置一下,application.properties 路径是
src/main/resources 下,对于 application.properties 更多的介绍请自行百度进行查找相关资料进
行查看,在此不进行过多的介绍,以下只是 mysql 的配置文件。
11 / 42
大体步骤:
(1)在 application.properties 中加入 datasouce 的配置
(2)在 pom.xml 加入 mysql 的依赖。
(3)获取 DataSouce 的 Connection 进行测试。
src/main/resouces/application.properties:
########################################################
###datasource
########################################################
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
pom.xml 配置:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
到此相关配置就 ok 了,那么就可以在项目中进行测试了,我们可以新建一个 class Demo 进行测试,实
体类创建完毕之后,我们可能需要手动进行编写建表语句,这时候我们可能就会想起 Hibernate 的好处
了。那么怎么在 spring boot 使用 Hibernate 好的特性呢?So easy,具体怎么操作,请看下篇之 JPA –
Hibernate。
6 Spring boot  配置 JPA
在说具体如何在 spring boot 使用 Hibernate 前,先抛装引玉些知识点?什么是 JPA 呢?
JPA 全称 Java Persistence API.JPA 通过 JDK 5.0 注解或 XML 描述对象-关系表的映射关系,并将运行
期的实体对象持久化到数据库中。
http://baike.baidu.com/link?url=LdqIXvzTr0RDjY2yoRdpogDdzaZ_L-
DrIOpLLzK1z38quk6nf2ACoXEf3pWKTElHACS7vTawPTmoFv_QftgT_q
接下里就说本文章重点了,那么怎么操作呢?只需要如下配置就可以了?
pom.xml 配置:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
12 / 42
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
application.properties 配置:
########################################################
###datasource
########################################################
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
########################################################
### Java Persistence Api
########################################################
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
那么就可以使用 Hibernate 带来的好处了,在实体类注解@Entity 就会自动进行表的 DDL 操作了
我们在 com.kfit.test.bean.Demo 中加入注解:@Entity
@Entity//加入这个注解,Demo 就会进行持久化了,在这里没有对@Table 进行配置,请自行配置。
publicclass Demo {
@Id @GeneratedValue
private long id;//主键.
13 / 42
private String name;//测试名称.
//其它代码省略.
这时候运行就会在数据库看到 demo 表了。
7 Spring boot  整合 JPA  保存 数据
总体步骤:
(1) 创建实体类 Demo,如果已经存在,可以忽略。
(2) 创建 jpa repository 类操作持久化。
(3) 创建 service 类。
(4) 创建 restful 请求类。
(5) 测试
代码如下:
com.kfit.test.bean.Demo :
i i mport javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*  TODO DEMO标的实体类映射
*
*  @author 
*  @Entity //加入这个注解,Demo就会进行持久化了
*/
@Entity
@Table(name = "DEMO", schema = "ROOT")
public c  class Demo {
@Id
@GeneratedValue
private Integer id;
@Column(name = "name")
private String name;
public Demo() {
super();
}
public Demo(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public  void setId(Integer id) {
14 / 42
this.id = id;
}
public String getName() {
return name;
}
public  void setName(String name) {
this.name = name;
}
}
com.kfit.test.dao.DemoRepository(这是一个接口,没有具体的实现,这就是 JPA):
i i mport org.springframework.data.repository.CrudRepository;
import com.hpit.springboot01.entity.Demo;
/**
*  TODO Demo表的DAO层接口,并没有具体的实现,继承基础CRUD实现
* 泛型1:实体类 泛型2:主键映射类型
*  @author 
*
*/
public  interface IDemoRepository  extends CrudRepository<Demo, Integer> {
}
到这里保存数据的方法就写完了。CrudRepository 类把一些常用的方法都已经进行定义和实现了。那
么你现在就可以在别的类引入调用了。
另外就是在 Spring Data 的核心接口里面 Repository 是最基本的接口了, spring 提供了很多实现了
该 接 口 的 基 本 接 口 ,如 :CrudRepository, PagingAndSortingRepository, SimpleJpaRepository,
QueryDslJpaRepository 等大量查询接口
com.kfit.test.service.DemoService :
i i mport com.hpit.springboot01.dao.IDemoRepository;
import com.hpit.springboot01.entity.Demo;
/**
*  TODO 简单业务逻辑层
*
*  @author 
*/
@Service("demoService") // 定义业务逻辑层
public  class DemoService {
@Autowired // 自动装配DAO
private IDemoRepository demoRepository;
@Transactional // 自动事务托管
public  void save(Demo demo) {
demoRepository.save(demo);
}
15 / 42
}
开发数据保存控制器:
i i mport org.springframework.beans.factory.annotation.Autowired;
import t org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.hpit.springboot01.entity.Demo;
import com.hpit.springboot01.services.DemoService;
/**
*  TODO 开发测试数据保存控制器
*
*  @author 
*
*/
@Controller
@RequestMapping("/demo2")
public  class DemoController {
@Autowired
private DemoService demoService;
@ResponseBody
@RequestMapping("/save")
public String save() {
demoService.save( new Demo("angle"));
return "ok the data was saved";
}
}
运行程序,查看效果:
8 Spring boot  使用 JdbcTemplate  保存 数据
整体步骤:
(1) 在 pom.xml 加入 jdbcTemplate 的依赖;
(2) 编写 DemoDao 类,声明为:@Repository,引入 JdbcTemplate
(3) 编写 DemoService 类,引入 DemoDao 进行使用
(4) 编写 Demo2Controller 进行简单测试。
16 / 42
具体操作流程如下:
使用 JdbcTemplate 类需要加入(如果在 JPA 已经加入的话,这个步骤就可以忽略了)
那么只需要在需要使用的类中加入:
@Resource
private JdbcTemplate jdbcTemplate;
这样就可以使用 jdbcTemplate 进行数据库的操作了。
比如:
String sql = "insert into Demo(name,age) values(?,?)";
jdbcTemplate.update(sql, new Object[]{demo.getName(),demo.getAge()});
具体案例
定义 Dao 层代码
i i mport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.hpit.springboot01.entity.Demo;
/**
*  TODO 使用JPA jdbc模板操作数据
*
*  @author
*
*/
@Repository("demoDao1")
public  class DemoDaoUseJdbcTemplate {
@Autowired //自动装配模板
private JdbcTemplate jdbcTemplate;
/**
*  TODO 根据主键获取数据
*  @param id 主键
*  @return 实体对象
*/
public Demo getById(Integer id) {
String sql = "select * from Demo where id = ?";
//获取数据映射
RowMapper<Demo> mapper =  new BeanPropertyRowMapper<>(Demo. class);
return jdbcTemplate.queryForObject(sql, mapper, id);
}
}
2.开发业务逻辑层
i i mport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hpit.springboot01.dao.DemoDaoUseJdbcTemplate;
17 / 42
import com.hpit.springboot01.entity.Demo;
/**
*  TODO 定义业务逻辑
*
*  @author 
*/
@Service("demoService2")
public  class DemoService2 {
@Autowired
private DemoDaoUseJdbcTemplate daoUseJdbcTemplate;
public Demo getById(Integer id) {
return daoUseJdbcTemplate.getById(id);
}
}
3.开发控制器
i i mport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.hpit.springboot01.entity.Demo;
import t com.hpit.springboot01.services.DemoService;
import com.hpit.springboot01.services.DemoService2;
/**
*  TODO 开发测试数据保存控制器
*
*  @author
*
*/
@Controller
@RequestMapping("/demo2")
public  class DemoController {
@Autowired
private DemoService demoService;
@Autowired
private DemoService2 demoService2;
@ResponseBody
@RequestMapping("/save")
public String save() {
demoService.save( new Demo("angle"));
return "ok the data was saved";
}
@ResponseBody
@RequestMapping("/show")
18 / 42
public Demo showDemo(@RequestParam(name = "no", defaultValue = "1", required =  true)
Integer id) {
return demoService2.getById(id);
}
}
4.启动应用,查看效果
当前前提是你的数据库中有 id=1 的数据了,不然会报错的:
org.springframework.dao.EmptyResultDataAccessException
9 Spring boot  常用 配 置
1. 程序 基本 配置
Spring boot 默认端口是 8080,如果想要进行更改的话,只需要修改 applicatoin.properties 文件,
在配置文件中加入:
server.port=9090
常用配置:
########################################################
###EMBEDDED SERVER CONFIGURATION (ServerProperties)
########################################################
#server.port=8080
#server.address= # bind to a specific NIC
#server.session-timeout= # session timeout in seconds
#the context path, defaults to '/'
#server.context-path=/spring-boot # 修改 默认 访问 路径
#server.servlet-path= # the servlet path, defaults to '/'
#server.tomcat.access-log-pattern= # log pattern of the access log
#server.tomcat.access-log-enabled=false # is access logging enabled
#server.tomcat.protocol-header=x-forwarded-proto # ssl forward headers
#server.tomcat.remote-ip-header=x-forwarded-for
#server.tomcat.basedir=/tmp # base dir (usually not needed, defaults to tmp)
19 / 42
#server.tomcat.background-processor-delay=30; # in seconds
#server.tomcat.max-threads = 0 # number of threads in protocol handler
#server.tomcat.uri-encoding = UTF-8 # character encoding to use for URL decoding
2. 修改 a java  编译版本
Spring Boot 在编译的时候,是有默认 JDK 版本的,如果我们期望使用我们要的 JDK 版本的话,那么要
怎么配置呢?
这个只需要修改 pom.xml 文件的<build> -- <plugins>加入一个 plugin 即可。
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
添加了 plugin 之后,需要右键 Maven à Update Projects,这时候你可以看到工程根目录下的 JRE
System Library 版本更改了。
10 Spring boot  静态 资源处理
默认 静态资源 处理
Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。
建议大家使用 Spring Boot 的默认配置方式,如果需要特殊处理的再通过配置进行修改。
如 果 想 要 自 己 完 全 控 制 WebMVC, 就 需 要 在 @Configuration 注 解 的 配 置 类 上 增 加 @EnableWebMvc
( @SpringBootApplication 注 解 的 程 序 入 口 类 已 经 包 含 @Configuration ) , 增 加 该 注 解 以 后
WebMvcAutoConfiguration 中配置就不会生效,你需要自己来配置需要的每一项。这种情况下的配置还
是要多看一下 WebMvcAutoConfiguration 类。
我们既然是快速使用 Spring Boot,并不想过多的自己再重新配置。本文还是主要针对 Spring Boot 的
默认处理方式,部分配置在 application 配置文件中(.properties 或 .yml)
默认资源映射
我们在启动应用的时候,可以在控制台中看到如下信息:
2016-01-08  09:29:30.362  INFO  24932  ---
[  main]o.s.w.s.handler.SimpleUrlHandlerMapping  :
MappedURLpath[/webjars/**]ontohandleroftype[class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-01-08  09:29:30.362  INFO  24932  ---
[  main]o.s.w.s.handler.SimpleUrlHandlerMapping  :
MappedURLpath[/**]ontohandleroftype[class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-01-08  09:29:30.437  INFO  24932  ---
[  main]o.s.w.s.handler.SimpleUrlHandlerMapping  :
MappedURLpath[/**/favicon.ico]ont
20 / 42
其中默认配置的 /** 映射到 /static (或/public、/resources、/META-INF/resources)
其中默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/
PS : 上 面 的 static 、 public 、 resources 等 目 录 都 在 classpath: 下 面 ( 如
src/main/resources/static) 。
如果我按如下结构存放相同名称的图片,那么 Spring Boot 读取图片的优先级是怎样的呢?
如下图:
当我们访问地址 http://localhost:8080/test.jpg 的时候,显示哪张图片?这里可以直接告诉大家,优先级顺
序为:META/resources > resources > static > public (已进行测试)
如果我们想访问 test2.jpg,请求地址 http://localhost:8080/img/test2.jpg
自定义 静态资源处理
面我们介绍了 Spring Boot 的默认资源映射,一般够用了,那我们如何自定义目录?
这些资源都是打包在 jar 包中的,然后实际应用中,我们还有很多资源是在管理系统中动态维护的,并
不可能在程序包中,对于这种随意指定目录的资源,如何访问?
自定义目录
以增加 /myres/*  映射到 classpath:/myres/* 为例的代码处理为:
实现类继承 WebMvcConfigurerAdapter 并重写方法 addResourceHandlers (对于访问 myres 文件夹中
的 test.jpg 图片的地址为 http://localhost:8080/myres/test.jpg
package org.springboot.sample.config;
import org.springboot.sample.interceptor.MyInterceptor1;
import org.springboot.sample.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MyWebAppConfigurer
extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
21 / 42
registry.addResourceHandler("/myres/**").addResourceLocations("classpath:/myres/");
super.addResourceHandlers(registry);
}
}
访问 myres 文件夹中的 test.jpg 图片的地址为 http://localhost:8080/myres/test.jpg
这样使用代码的方式自定义目录映射,并不影响 Spring Boot 的默认映射,可以同时使用。
如 果 我 们 将 /myres/*  修 改 为 /* 与 默 认 的 相 同 时 , 则 会 覆 盖 系 统 的 配 置 , 可 以 多 次 使
用 addResourceLocations 添加目录,优先级先添加的高于后添加的。
其 中 addResourceLocations  的 参 数 是 动 参 , 可 以 这 样
写 addResourceLocations(“classpath:/img1/”, “classpath:/img2/”, “classpath:/img3/”);
使用外部目录
如 果 我 们 要 指 定 一 个 绝 对 路 径 的 文 件 夹 ( 如 D:/data/api_files ), 则 只 需 要 使
用 addResourceLocations 指定即可。
// 可以直接使用 addResourceLocations 指定磁盘绝对路径,同样可以配置多个位置,注意路径写
法需要加上 file:
registry.addResourceHandler("/api_files/**").addResourceLocations("file:D:/data/api_file
s");
11 Srping boot  实现 任务 调度
spring boot 实现任务调度非常简单,只需要在调度类头上添加@Configuration,然后再调度方法上
添加@Schuldle 注解,并为@Schuldle 指定 CronExpress 表达式。
代码如下:
i i mport org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@Configuration // 声明类为系统配置类
@EnableScheduling // 开启调度任务
public  class MyScheduleConfig {
private Logger logger = Logger. getLogger (getClass());
@Scheduled(cron = "0 0/1 * * * ?") // 定义调度器
pu blic  void job1() {
logger.info("this is my first job execute");
}
}
22 / 42
12 Spring boot  普通 类调用 Bean
我们知道如果我们要在一个类使用 spring 提供的 bean 对象,我们需要把这个类注入到 spring 容器
中,交给 spring 容器进行管理,但是在实际当中,我们往往会碰到在一个普通的 Java 类中,想直接
使用 spring 提供的其他对象或者说有一些不需要交给 spring 管理, 但是需要用到 spring 里的一些对
象。如果这是 spring 框架的独立应用程序,我们通过:
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
这样的方式就可以很轻易的获取我们所需要的对象。
但是往往我们所做的都是 Web Application, 这时我们启动 spring容器是通过在 web.xml文件中配置,
这样就不适合使用上面的方式在普通类去获取对象了,因为这样做就相当于加载了两次 spring 容器,
而我们想是否可以通过在启动 web 服务器的时候,就把 Application 放在某一个类中,我们通过这个
类在获取,这样就可以在普通类获取 spring bean 对象了,让我们接着往下看。
普通类调用 Spring bean 对象:
可以参考:http://412887952-qq-com.iteye.com/blog/1479445
这里有更多这方面的介绍,比较详细,在这里只是抛装引玉说明在 Spring Boot 是如何进行调用的。
在 Spring Boot 可以扫描的包下
假设我们编写的工具类为 SpringUtil。
如果我们编写的 SpringUtil 在 Spring Boot 可以扫描的包下或者使用@ComponentScan 引入自定义的
包了,那么原理很简单,只需要使得 SpringUtil 实现接口:ApplicationContextAware,然后加上
@Component 注解即可,具体编码如下:
p p ackage com.hpit.springboot01.util;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* spring工具类,为了更方便的获取spring的applicationContext 直接实现接口
ApplicationContextAware
*
*  @author 
*
*/
@Component
public  class SpringUtil  implements ApplicationContextAware {
private Logger logger = Logger. getLogger (getClass());
private  static ApplicationContext  applicationContext ;
@Override
public  void setApplicationContext(ApplicationContext applicationContext)  throws
BeansException {
if (SpringUtil. applicationContext ==  null) {
SpringUtil. applicationContext = applicationContext;
}
logger.info(
23 / 42
"========ApplicationContext配置成功,在普通类可以通过调用
SpringUtils.getApplicationContext()获取applicationContext对象,applicationContext="
+ SpringUtil. applicationContext + "========");
}
/**
* 获取spring上下午
*
*  @return
*/
public  static ApplicationContext getApplicationContext() {
return  applicationContext ;
}
public  static Object getBean(String beanName) {
return  applicationContext .getBean(beanName);
}
public  static <T> Object getBean(Class<T> class1) {
return  applicationContext .getBean(class1);
}
public  static <T> Object getBean(Class<T> class1, String beanName) {
return  applicationContext .getBean(class1, beanName);
}
}
不在 Spring Boot 的扫描包下方式一
这 种 情 况 处 理 起 来 也 很 简 单 , 先 编 写 SpringUtil 类 , 同 样 需 要 实 现 接 口 :
ApplicationContextAware,具体编码如下:
simple.plugin.spring.SpringUtil
package simple.plugin.spring;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringUtil implements ApplicationContextAware{
private static ApplicationContext  applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
if(SpringUtil. applicationContext == null){
SpringUtil. applicationContext = applicationContext;
}
System. out .println("---------------------------------------------------------------------");
System. out .println("---------------------------------------------------------------------");
System. out .println("---------------simple.plugin.spring.SpringUtil--------------------------------------
----------------");
System. out .println("========ApplicationContext 配 置 成 功 , 在 普 通 类 可 以 通 过 调 用
SpringUtils.getAppContext() 获 取 applicationContext 对
24 / 42
象,applicationContext="+SpringUtil. applicationContext +"========");
System. out .println("---------------------------------------------------------------------");
}
//获取 applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext ;
}
//通过 name 获取 Bean.
public static Object getBean(String name){
return  getApplicationContext ().getBean(name);
}
//通过 class 获取 Bean.
public static <T> T getBean(Class<T> clazz){
return  getApplicationContext ().getBean(clazz);
}
//通过 name,以及 Clazz 返回指定的 Bean
public static <T> T getBean(String name,Class<T> clazz){
return  getApplicationContext ().getBean(name, clazz);
}
}
之后这一步才是关键,使用@Bean 注解,在 App.java 类中将 SpringUtil 注解进来,代码如下:
package com.kfit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import simple.plugin.spring.SpringUtil;
/**
* Hello world!
*
*/
// 其中@SpringBootApplication 让 申明让 spring boot  自动给程序进行必要的配置,等价于以默认属性使用
@Configuration ,@EnableAutoConfiguration  和@ComponentScan
@SpringBootApplication
@ServletComponentScan
public class App {
/**册 注册 Spring Util
25 / 42
*  这里为了和上一个 冲突,所以方面名为:springUtil2
* 用 实际中使用 springUtil
*/
@Bean
public SpringUtil springUtil2(){return new SpringUtil();}
/**
*
参数里 VM  参数设置为:
-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
不在 Spring Boot 的扫描包下方式二
代码基本和上面都是相同的,主要是在 App.java 中使用@Import 进行导入。
而且在 SpringUtil 是不需要添加@Component 注解
@SpringBootApplication
@ServletComponentScan
@Import(value={SpringUtil.class})
publicclass App {
//省略其它代码.
}
说明以上 3 中方式都生效了,这 3 中方式根据实际情况选择一种方式就可以了。
那么这样子在普通类既可以使用:
SpringUtil.getBean() 获取到 Spring IOC 容器中的 bean。
当然也可以在 Spring 管理的类中使用:
@Resouce 或者@Autowired 进行注入使用, 当然我们这个类的核心是普通类可以调用 spring 的 bean 进
行使用了,是不是很神奇呢。
13 spring boot  使用模板引擎
使用 thymeleaf 模板引擎
26 / 42
整体步骤:
(1) 在 pom.xml 中引入 thymeleaf;
(2) 如何关闭 thymeleaf 缓存
(3) 编写模板文件.html
Spring Boot 默认就是使用 thymeleaf 模板引擎的,所以只需要在 pom.xml 加入依赖即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Thymeleaf 缓存在开发过程中,肯定是不行的,那么就要在开发的时候把缓存关闭,只需要在
application.properties 进行配置即可:
########################################################
###THYMELEAF (ThymeleafAutoConfiguration)
########################################################
#spring.thymeleaf.prefix=classpath:/templates/
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.mode=HTML5
#spring.thymeleaf.encoding=UTF-8
# ;charset=<encoding> is added
#spring.thymeleaf.content-type=text/html
# set to false for hot refresh
spring.thymeleaf.cache=false
编写模板文件 src/main/resouces/templates/helloHtml.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello.v.2</h1>
<p th:text="${hello}"></p>
</body>
</html>
编写访问路径(com.kfit.test.web. ThymeleafController):
i i mport java.util.Map;
27 / 42
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*  TODO thymeleaf模板引擎控制器
*  @author Administrator
*
*/
@Controller
public  class ThymeleafController {
@RequestMapping("/helloHtml")
public String hello(Map<String, Object> map) {
map.put("hello", "this data is from backing server");
r r eturn "helloHtml";
}
}
启动应用,输入地址:http://127.0.0.1:8080/helloHtml 会输出:
使用 freemarker 模板引擎
使用 freemarker 也很简单,
在 pom.xml 加入 freemarker 的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
剩下的编码部分都是一样的,说下 application.properties 文件:
########################################################
###FREEMARKER (FreeMarkerAutoConfiguration)
########################################################
spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
28 / 42
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
#spring.freemarker.prefix=
#spring.freemarker.request-context-attribute=
#spring.freemarker.settings.*=
#spring.freemarker.suffix=.ftl
#spring.freemarker.template-loader-path=classpath:/templates/#comma-separatedlist
#spring.freemarker.view-names= #whitelistofviewnamesthatcanberesolved
开发 freemarker 模板
helloHtml1.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset= "UTF-8" >
<title>freemarker模板的使用</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
开发控制器:
i i mport org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*  TODO freemarker 控制器
*
*  @author 
*
*/
@Controller
@RequestMapping("/freemarker")
public  class FreemarkerController {
@RequestMapping("/hello")
public String hello(ModelMap map) {
map.put("message", "this data is from backing server , for freemarker");
return "helloHtml1";
}
}
访问地址:http://localhost:8080/freemarker/hello
29 / 42
thymeleaf 和 freemarker 是可以共存的。
14 Spring boot  集成 JSP
这个部分比较复杂,所以单独创建一个工程来进行讲解;
大体步骤:
(1)创建 Maven web project;
(2)在 pom.xml 文件添加依赖;
(3)配置 application.properties 支持 jsp
(4)编写测试 Controller
(5)编写 JSP 页面
(6)编写启动类 App.java
1,FreeMarker
2,Groovy
3,Thymeleaf (Spring 官网使用这个)
4,Velocity
5, JSP (貌似 Spring Boot官方不推荐, STS创建的项目会在 src/main/resources 下有个 templates 目
录,这里就是让我们放模版文件的,然后并没有生成诸如 SpringMVC 中的 webapp 目录)
不过本文还是选择大家都熟悉的 JSP 来举例,因为使用 JSP 与默认支持的模版需要特殊处理,所以拿
来举例更好。
(1)创建 Maven web project
使用 Eclipse 新建一个 Maven Web Project ,项目取名为:
springboot02
(2)在 pom.xml 文件添加依赖
<!-- spring boot parent 节点,引入这个之后,在下面和 spring boot 相关的就不需要引入版本了; -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
依赖包:
<!-- web 支持: 1、web mvc; 2、restful; 3、jackjson 支持; 4、aop ........ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
30 / 42
<!-- servlet 依赖. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!--
JSTL(JSP Standard Tag Library,JSP 标准标签库)是一个不断完善的开放源代码的 JSP 标
签库,是由 apache 的 jakarta 小组来维护的。JSTL 只能运行在支持 JSP1.2 和 Servlet2.3 规范的容器上,
如 tomcat4.x。在 JSP 2.0 中也是作为标准支持的。
不然报异常信息:
javax.servlet.ServletException: Circular view path [/helloJsp]: would
dispatch back to the current handler URL [/helloJsp] again. Check your ViewResolver
setup! (Hint: This may be the result of an unspecified view, due to default view name
generation.)
-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- tomcat 的支持.-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Jdk 编译版本:
<build>
31 / 42
<finalName>spring-boot-jsp</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
(3)application.properties 配置
上面说了 spring-boot 不推荐 JSP,想使用 JSP 需要配置 application.properties。
添加 src/main/resources/application.properties 内容:
# 页面默认前缀目录
spring.mvc.view.prefix=/WEB-INF/views/
# 响应页面默认后缀
spring.mvc.view.suffix=.jsp
# 自定义属性,可以在 Controller 中读取
application.hello=Hello Angel From application
(4)编写测试 Controller
编写类:com.hpit.sb.controller. HelloJSPController:
i i mport org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*  TODO 开发控制器,该控制器将返回到JSP视图
*
*  @author 
*/
@Controller
public  class HelloJSPController {
@RequestMapping("/index")
public String hello(ModelMap map) {
map.put("message", "this data is from the backing server");
return "index";
}
}
32 / 42
(5)编写 JSP 页面
在 src/main 下面创建 webapp/WEB-INF/views 目录用来存放我们的 jsp 页面:index.jsp
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
pageEncoding= "UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" >
<title>hello jsp</title>
</head>
<body>
${message }
</body>
(6)编写启动类
编写 App.java 启动类:
i i mport org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public  class App {
public  static  void main(String[] args)  thro ws Exception {
SpringApplication. run (App. class, args);
}
}
运行程序,访问页面:
附注:关于集成 JSP 几个问题:
1、Spring Boot 使用 jsp 时,仍旧可以打成 jar 包的形式吗?
2、Spring Boot 使用 jsp 时,比如说 css,image,js 等三种静态资源文件,应该放在什么目录下?这些静态资源映
射,在 spring boot 中具体应该怎么做?
例如,下面是 spring 中做的静态资源映射,但是在 spring boot 中不知道怎么处理:
<!-- springmvc.xml 资源映射 -->
<mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
<mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
<mvc:resources location="/WEB-INF/image/" mapping="/image/**"/>
3、下面这个 tomcat 的包必须导入吗,spring-boot-starter-web 中不是有一个内嵌的 tomcat 吗?
<dependency>
33 / 42
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<1>、针对第一个问题,答案是不可以的。
我们先看一段英文描述,如下:
When running a Spring Boot application that uses an embedded servlet container (and is
packaged as an executable archive), there are some limitations in the JSP support.
With Tomcat it should work if you use war packaging, i.e. an executable war will work,
and will also be deployable to a standard container (not limited to, but including Tomcat).
An executable jar will not work because of a hard coded file pattern in Tomcat.
Jetty does not currently work as an embedded container with JSPs.
Undertow does not support JSPs.
原文的大体意思就是:Tomcat 支持 war 的打包方式,spring boot 支持 war 打包方式。Jetty
现在不支持 JSP 嵌入容器。Undertow 根本就不支持 JSP。
所以答案就是打包成 war,jsp 会自然按照 servlet 的标准部署。但也就意味着你不可以用嵌
入式的方式运行,而是 Tomcat Server + war 的部署方式。
看到这里有些网友肯定会有疑问那什么是嵌入式的 web 服务器?我们这边就拿 jetty 来说明
下。
Jetty 可以非常容易的嵌入到应用程序当中而不需要程序为了使用 Jetty 做修改。
从某种程度上,你也可以把 Jetty 理解为一个嵌入式的 Web 服务器。所以我们经常会说嵌入
式 jetty。
Jetty 有一个口号:不要把你的应用部署到 Jetty 中,把 Jetty 部署到你的应用中。Jetty 可
以在 Java 应用程序中向其他 POJO 一样被实例化,换句话说,以嵌入式的模式运行 Jetty 是指将 Http
模块放入你的应用程序中,而非部署你的程序到一个 HTTP 服务器。这就是所谓的嵌入式 jetty。
另外在说明一点就是 JSP 解析是需要 JSP 引擎处理的,tomcat 就提供了 JSP 处理引擎。所以
很显然 JSP 是依赖容器而存在的,不然就没法访问了。那么既然是依赖于 tomcat 的话。
有一网友找到一支持打成 jar 包运行的插件:
Using Spring Boot with JSPs in Executable Jars
https://github.com/ghillert/spring-boot-jsp-demo
经过 java -jar xxx.jar 运行后,可以正常访问网页。
这也可以说明原本是不支持的,但是如果非要支持的话,那么需要进行使用插件进行支持。
<2>针对第二个问题
对于第二个问题,如果看过之前的章节就很好解决了,只需要在 src/main/resouces 下新建一
个 static 目录,然后在 static 下新建子目录:css,images,js 目录,在 images 放入一张 test.jpg 图
片,那么访问路径是:http://127.0.0.1:8080/images/test.jpg
当前目录结构应该是这样子的:
(1)--src/java/resources
(2)-- static
(3)-- css
(3)-- images
34 / 42
(3)-- js
那么有人会有疑问这个,打包的时候能打上嘛,答案是可以的,请看实际打包解压图:
15 Spring boot  集成 servlet
Web 开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet、Filter、
Listener、Interceptor 等等。
当使用 Spring-Boot 时,嵌入式 Servlet 容器通过扫描注解的方式注册 Servlet、Filter 和 Servlet
规范的所有监听器(如 HttpSessionListener 监听器) 。
Spring boot 的主 Servlet 为 DispatcherServlet,其默认的 url-pattern 为“/” 。也许我们在应用
中还需要定义更多的 Servlet,该如何使用 SpringBoot 来完成呢?
在 spring boot 中添加自己的 Servlet 有两种方法,代码注册 Servlet 和注解自动注册(Filter 和
Listener 也是如此) 。
在 spring boot 中添加自己的 Servlet 有两种方法,代码注册 Servlet 和注解自动注册(Filter 和
Listener 也是如此) 。
一 、 代 码 注 册 通 过 ServletRegistrationBean 、 FilterRegistrationBean  和
ServletListenerRegistrationBean 获得控制。
也可以通过实现 ServletContextInitializer 接口直接注册。
二、在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener
可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
通过代码注册 Servlet 示例代码:
com.hpit.sb.servlet.MyServlet1
i i mport java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*  TODO 开发一个普通的servlet
*
*  @author 
*
*/
@WebServlet(urlPatterns = "/myServlet/*", name = "servlet1", description = "this is my
first servlet in spring boot")
public  class MyServlet1  extends HttpServlet {
private  static  final  long  serialVersionUID = 6613439809483079873L;
35 / 42
@Override
protected  void doGet(HttpServletRequest req, HttpServletResponse resp)  throws
ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>这是:MyServlet1</h1>");
out.println("</body>");
out.println("</html>");
}
}
程序入口配置:
com.hpit.sb. App
i i mport org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.hpit.sb.servlet.MyServlet1;
/**
*
*
* 大家也许会看到有些demo使用了3个注解:  @Configuration;
*
*  @EnableAutoConfiguration
*  @ComponentScan 其实:@SpringBootApplication申明让spring boot自动给程序进行必要的配置,
* 等价于以默认属性使用@Configuration,
*  @EnableAutoConfiguration 和@ComponentScan 所以大家不要被一些文档误导了,让自己很迷茫了,
希望本文章对您有所启发;
*
*  @author 
*/
@SpringBootApplication
public  class App {
/**
* 注册Servlet.不需要添加注解:@ServletComponentScan
* 这种方式已经在springboot中废弃
*  @return
*/
@Bean
public ServletRegistrationBean regMyServlet1() {
return  new ServletRegistrationBean( new MyServlet1(), "/myServlet/*");
}
public  static  void main(String[] args)  throws Exception {
SpringApplication. run (App. class, args);
}
}
36 / 42
第二种方式:使用注解注册 Servlet 示例代码
com.hpit.sb.servlet. MyServlet2
i i mport javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*  TODO 使用注解开发第二个servlet,该servlet将使用注解注册
*
*  @author 
*
*/
@WebServlet(urlPatterns = "/myServlet/*", name = "serlvet2", description = "this is the
second spring boot servlet")
public  class MyServlet2  extends HttpServlet {
private  static  final  long  serialVersionUID = -7877622076081913248L;
@Override
protected  void doGet(HttpServletRequest req, HttpServletResponse resp)  throws
ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>这是:MyServlet1</h1>");
out.println("</body>");
out.println("</html>");
}
}
主程序配置:
com.hpit.sb.App
i i mport org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import com.hpit.sb.servlet.MyServlet1;
/**
*
*
* 大家也许会看到有些demo使用了3个注解:  @Configuration;
*
*  @EnableAutoConfiguration
*  @ComponentScan 其实:@SpringBootApplication申明让spring boot自动给程序进行必要的配置,
* 等价于以默认属性使用@Configuration,
*  @EnableAutoConfiguration 和@ComponentScan 所以大家不要被一些文档误导了,让自己很迷茫了,
希望本文章对您有所启发;
*
37 / 42
*  @author 
*/
@SpringBootApplication
@ServletComponentScan // 方式二: 添加servlet 注册扫描,将自动注册添加了@WebServlet的类为
serlvet
public  class App {
/**
* 方式一:注册Servlet.不需要添加注解:@ServletComponentScan 这种方式已经在springboot中
废弃
*
*  @return
*/
/*
* @Bean public ServletRegistrationBean regMyServlet1() { return new
* ServletRegistrationBean(new MyServlet1(), "/myServlet/*"); }
*/
public  static  void main(String[] args)  throws Exception {
SpringApplication. run (App. class, args);
}
}
启动日志:
16 Spring boot  集成 Fliter 和 和 Linstener
上一章已经对定义 Servlet 的方法进行了说明,过滤器(Filter)和监听器(Listener)的注册方法
和 Servlet 一样, 不清楚的可以查看下上一篇文章 (20) : 本文将直接使用@WebFilter 和@WebListener
的方式,完成一个 Filter 和一个 Listener;使用注解
@ServletComponentScan//这个就是扫描相应的 Servlet 包;
开发 Filter: 【添加 @ServletComponentScan 注解之后,使用注解开发的 Filter 和 Linstener 将会
被自动注册】
具体实现代码:
com.hpit.sb.filter.MyFilter
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import org.apache.log4j.Logger;
38 / 42
//使用注解定义一个过滤器
@WebFilter(urlPatterns = "/*", filterName = "myFilter")
public  class MyFilter  implements Filter {
private Logger logger = Logger. getLogger (getClass());
@Override
public  void destroy() {
logger.info("destroy()");
}
@Override
public  void doFilter(ServletRequest request, ServletResponse response, FilterChain
chain)
throws IOException, ServletException {
logger.info("doFilter()");
logger.info("before filter");
chain.doFilter(request, response);
logger.info("after filter");
}
@Override
public  void init(FilterConfig config)  throws ServletException {
logger.info("init()");
}
}
开发 Linstener
具体实现代码:
com.hpit.sb.listener. Mylistener
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.apache.log4j.Logger;
/**
*  TODO 使用注解开发一个监听器
*
*  @author 
*
*/
@WebListener
public  class Mylistener  implements ServletContextListener {
private Logger logger = Logger. getLogger (getClass());
@Override
public  void contextDestroyed(ServletContextEvent contextEvent) {
logger.info("contextDestroyed");
}
@Override
public  void contextInitialized(ServletContextEvent contextEvent) {
39 / 42
logger.info("contextInitialized");
}
}
启动日志,并请求一个有效连接:
17 Spring boot  拦截器 HandlerInterceptor
上一章对过滤器的定义做了说明,也比较简单。过滤器属于 Servlet 范畴的 API,与 Spring 没什么关
系。
Web 开 发 中 , 我 们 除 了 使 用 Filter 来 过 滤 请 web 求 外 , 还 可 以 使 用 Spring 提 供 的
HandlerInterceptor(拦截器) 。
HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在 request 被响应之前、
request 被响应之后、视图渲染之前以及 request 全部结束之后。我们不能通过拦截器修改 request 内
容,但是可以通过抛出异常(或者返回 false)来暂停 request 的执行。
实现 UserRoleAuthorizationInterceptor 的拦截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor
其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比较常用。
40 / 42
配置拦截器也很简单,Spring 为什么提供了基础类 WebMvcConfigurerAdapter ,我们只需要重写
addInterceptors 方法添加注册拦截器。
实现自定义拦截器只需要 3 步:
1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
2、创建一个 Java 类继承 WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
2、 实例化我们自定义的拦截器, 然后将对像手动添加到拦截器链中 (在 addInterceptors 方法中添加) 。
PS:本文重点在如何在 Spring-Boot 中使用拦截器,关于拦截器的原理请大家查阅资料了解。
代码:
com.hpit.sb.interceptors. MyInterceptor1
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*  TODO 使用常规的方式开发springmvc拦截器1
*
*  @author 
*/
public  class MyInterceptor1  implements HandlerInterceptor {
private Logger logger = Logger. getLogger (getClass());
@Override
public  void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object object,
Exception exception)  throws Exception {
logger.info("afterCompletion...");
}
@Override
public  void postHandle(HttpServletRequest request, HttpServletResponse response, Object
object,
ModelAndView modelAndView)  throws Exception {
logger.info("postHandle...");
}
@Override
public  boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object object)  throws Exception {
logger.info("preHandle...");
return  true;
}
}
com.hpit.sb.interceptors. MyInterceptor2
41 / 42
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*  TODO 使用常规的方式开发springmvc拦截器2
*
*  @author 
*
*/
public  class MyInterceptor2  implements HandlerInterceptor {
private Logger logger = Logger. getLogger (getClass());
@Override
public  void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object object,
Exception exception)  throws Exception {
logger.info("afterCompletion...");
}
@Override
public  void postHandle(HttpServletRequest request, HttpServletResponse response, Object
object,
ModelAndView modelAndView)  throws Exception {
logger.info("postHandle...");
}
@Override
public  boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object object)  throws Exception {
logger.info("preHandle...");
return  true;
}
}
重写 web 配置 addInterceptors()方法,添加自定义拦截器:
com.hpit.sb.config. MyWebAppConfig
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.hpit.sb.interceptors.MyInterceptor1;
import com.hpit.sb.interceptors.MyInterceptor2;
/**
*  TODO 重写webmvc配置
*  @author 
*
*/
@Configuration

public  class MyWebAppConfig  extends WebMvcConfigurerAdapter {

@Override
public  void addInterceptors(InterceptorRegistry registry) {
// 重写addInterceptors方法并为拦截器配置拦截规则
registry.addInterceptor( new MyInterceptor1()).addPathPatterns("/**");
registry.addInterceptor( new MyInterceptor2()).addPathPatterns("/**");
//排除路径
//registry.addInterceptor(new
MyInterceptor2()).addPathPatterns("/**").excludePathPatterns("/Hello");
super.addInterceptors(registry);
}
}

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值