SpringBoot2视频学习笔记
工具的安装和使用
Eclipse安装SpringBoot相关插件
1.打开SpringBoot官网 https://spring.io/projects/spring-boot

最近版本

2.插件地址:https://spring.io/tools/sts/all

点击下载最新版本插件

3.打开eclipse ,点击菜单上的help—>Install New Software

4.点击add按钮,点击Archive按钮,选择本地插件路径位置,如下图:

5.选择所有的IDE项,选择不更新,点击下一步,如下图:

6.安装完成后,重启eclipse
spring官网下载spring优化后的Eclipse

2.将解压后目录下的STS.exe上右键,—>发送到—>桌面快捷方式,如下图:

使用方式和Eclipse一样
3.打开后,界面如下:

创建Spring Boot项目
上面两种方式,创建Spring Boot项目的方式是一样的,具体步骤如下:
1.项目工程处,右键—>new—>Spring Starter Project

如果new后面没有Spring Starter Project,执行如下步骤:
项目工程处,右键—>new—>Other,出现如下图弹框:

Wizards下面输入spring后,Spring Starter Project,点击next
2.填写好配置后,点击next,如下图:

3.选择Spring Boot 版本和项目类型,如下图,我选择了2.0.2和web

点击finish
4.项目创建完成之后,目录机构如下图:

RESTfull API简单项目的快速搭建
Eclipse快速打开项目文件所在位置
1.如图,菜单上右键点击Run—>External Tools—>External Tools Configurations…

2.在Program上右键,选择New,如下图:

3.配置参数,如下图:

4.勾选Common下的External Tools,点击Apply后点击Run

5.以后打开文件,只需要选中文件后,点击下图按钮即可,如图:

RESTFull API简单项目搭建
eclipse装完STS插件和使用spring提供的eclipse搭建spring boot项目的方式是一样的,如果项目是spring boot的项目,建议使用STS,对spring的兼容很好。
基本SpringBoot项目示例
1.项目创建过程参考 创建Spring Boot项目 单元
2.创建HelloController,如下图:

代码:
package com.cht.demo1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello spring boot ...";
}
}
3.启动项目,如下图:

4.访问项目,结果如下:

SpringBoot热部署
添加spring-boot-devtools热部署依赖,快捷方式如下:

或者手动在项目的pom.xml文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
重启项目
这个作用就会修改了项目中的东西之后,springboot会自动将修改了的文件重新加载,不会重启tomcat和重新将项目的所有文件都加载一遍。
添加RESTFull支持
主要改变在@Controller注解替换为@RestController注解,@RestController注解是一个组合注解,源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
可见,@RestController注解包含了@ResponseBody注解,所以,它下面的controller所有方法,返回的都是JSON数据,本demo中的应用如下:
1.创建User对象
package com.cht.demo1.bean;
import java.util.Date;
public class User {
private int id;
private String name;
private Date date;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
2.创建RestFullController,代码如下:
package com.cht.demo1.controller;
import java.util.Date;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cht.demo1.bean.User;
@RestController
@RequestMapping("/rest")
public class RestFullHelloController {
@RequestMapping("/getUser/{id}/{name}")
public User getUser(@PathVariable int id, @PathVariable String name) {
User user = new User();
user.setId(id);
user.setName(name);
user.setDate(new Date());
return user;
}
}
3.浏览器请求RestController下的接口,如下图:

SpringBoot单元测试
1.在要创建单元测试的controller类上右键,如下图:

2.配置测试类位置和类名等基本配置,如下图:

3.选择要测试的方法,如下图:

4.自动创建完成后的测试类如下:
package com.cht.demo1.controller;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
public class HelloControllerTest {
@Test
public void testHello() {
fail("Not yet implemented");
}
}
5.编写测试类,代码如下:
package com.cht.demo1.controller;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloControllerTest {
private MockMvc mockMvc;
@Before
public void before() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
}
@Test
public void testHello() throws Exception {
RequestBuilder reBuilder = get("/hello");
mockMvc.perform(reBuilder).andExpect(status().isOk()).andExpect(content().string("hello spring boot ..."));
}
}
6.运行测试,如下图:

绿色说明,测试通过,其他的controller测试类似。
springboot的打包
1.pom.xml中添加SpringBoot打包插件,代码如下:
<!-- springboot 打包插件,作用就是将SpringBoot依赖的jar包导进打的jar包进去 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
2.配置maven打包命令,如下图:


此maven命令的意思是先清除掉上次打的包,再重新打包
3.点击运行时,一般会报如下错误:

4.配置eclipse的JDK,如下图:

maven命令打包时,报错是应为项目使用的是jre,改成本地安装的jdk即可。
5.重新运行打包命令,打包结果如下:

在target目录下会出现项目的jar文件,如下图:

6.打开target所在目录之后,将cmd命令窗口切换到该目录,运行 java -jar 打包的文件名 运行打包的项目,如下图:

浏览器可以正常请求访问,如下图:

配置文件详解:properties与yaml
properties
配置文件的生效顺序,会对值进行覆盖:
1.@TestPropertySource注解
2.命令行参数
3.Java系统属性(System.getProperties())
4.操作系统环境变量
5.只有在random.*里包含的属性会产生一个 RandomValuePropertySource
6.在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
7.在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
8.在@Configuration类上的@PropertySource注解
9.默认属性(使用SpringApplication.setDefaultProperties指定)
配置随机值
roncoo.secret=${random.value}
roncoo.number=${random.int}
roncoo.bignumber=${random.long}
roncoo.number.less.than.ten=${random.int(10)}
roncoo.number.in.range=${random.int[1024,65536]}
读取使用注解:@Value(value=”${roncoo.secret}”)
注:出现黄点提示,是要提示配置元数据,可以不配置
属性占位符
当application.properties里的值被使用时,它们被存在的Environment过滤,所以你能够引用先前定义的值(比如,系统属性)。
roncoo.name=www.roncoo.com
roncoo.desc=${roncoo.name} is a domain name
Application属性文件,按优先级排序,位置高的将覆盖位置低的
1.当前目录下的一个/config子目录
2.当前目录
3.一个classpath下的/config包
4.classpath根路径(root)
这个列表是按照优先级排序的(列表中位置高的将覆盖位置低的)
配置应用端口和其他配置的介绍
端口配置:server.port=8090
时间格式化:spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
配置时区:spring.jackson.time-zone=Asia/wuhan
配置文件-多环境配置
一、多环境配置的好处
1.不同环境配置可以配置不同的参数
2.便于部署,提高效率,减少出错
二、properties多环境配置
1.配置激活选项 spring.profiles.active=dev
2.添加其他配置文件
application-dev.properties
application-prod.properties
application-test.properties
application.properties
YAML多环境配置
1.配置激活选项
spring:
profiles:
active: dev
2.在配置文件添加三个英文状态下的短横线即可区分
---
spring:
profiles: dev
yaml
一、YAML是什么?
YAML是YAML Ain’t Markup Language递归缩写,是YAML不是标记语言的意思,读音“yamel”(或者“雅梅尔”)。YAML是便于人阅读基于unicode编码的各种语言的序列号标准。它的用途广泛,用于配置文件,日志文件,跨语言数据共享,对象持久化,复杂的数据结构。
二、yaml有什么特性,为什么使用yaml?
1、易于阅读;使用缩进,冒号(:),破折号(-)等人易于理解方式显示复杂的数据结构。
2、YAML数据在语言之间可以移植的。
3、符合敏捷语言的数据结构。
4、支持一次性操作。
5、具有表现力和可扩展性。
6、易于实现和使用
三、YAML与JSON
形同点:
1、YAML和JSON都是便于人阅读的数据交换格式。
不同点:
1、JSON设计主要在于简单和通用。YAML设计主要在于易于阅读和支持任何复杂的数据结构。
2、YAML可以视为JSON的超集,提供更易于阅读和复杂的信息模型。
3、每个JSON文件都是一个YAML文件,从JSON到YAML迁移是很容易的事情。
四、YAML与XML
YAML主要是数据序列号语言。XXML设计是对SGML的向后兼容。XML有设计约束,而YAML没有。
两种配置方式的比较
1.properties配置多环境,需要添加多个配置文件,YAML只需要一个配置文件
2.书写格式的差异,yaml相对比较简洁,优雅
3.yaml的缺点:不能通过@PropertySource注解加载。如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件
如何使用java -jar demo-1.jar --spring.profiles.active=dev
日志配置logback和log4j2
支持日志框架:Java Util Logging, Log4j2 and Logback,默认使用logback
配置方式:默认配置文件配置和引用外部配置文件配置
默认配置文件配置(不建议使用:不够灵活,对log4j2等不够友好
//日志文件名,比如:roncoo.log,或者是/var/log/roncoo.loglogging.file=roncoo.log
//日志级别配置,比如:logging.level.org.springframework=DEBUGlogging.level.*=infologging.level.org.springframework=DEBUG
引用外部配置文件
logback配置方式:
spring boot 默认加载 classpath:logback-spring.xml 或者 classpath:logback-spring.groovy
使用自定义配置文件,配置方式为:
logging.config=classpath:logback-roncoo.xml
注意:不要使用 logback 这个来命名,否则spring boot将不能完全实例化
1.1使用基于spring boot的配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
自定义配置
2.1 log4j配置
2.2.1 去除logback的依赖包,添加log4j2的依赖包
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
<!-- 使用log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2.2.2 在classpath添加log4j2.xml或者log4j2-spring.xml(spring boot 默认加载)
2.3 自定义配置文件
比较
性能比较:log4j2和logback都优于log4j(不推荐使用)
配置方式:logback最简洁,spring boot默认,推荐使用
spring boot web应用开发
一、spring boot的web应用开发,是基于spring mvc
二、Spring boot在spring默认基础上,自动配置添加了以下特性:
- 包含了ContentNegotiatingViewResolver和BeanNameViewResolver beans。
- 对静态资源的支持,包括对WebJars的支持。
- 自动注册Converter,GenericConverter,Formatter beans。
- 对HttpMessageConverters的支持
- 自动注册MessageCodeResolver。
- 对静态index.html的支持。
- 对自定义Favicon的支持。
- 主动使用 ConfigurableWebBindingInitializer bean
三、模板引擎的选择
FreeMarker
Thymeleaf
Velocity(1.4版本之后弃用Spring Framework4.3版本之后弃用)
Groovy
Mustache
注:jsp应该尽量避免使用,原因如下:
- jsp只能打包为war格式,不支持jar格式,只能在标准的容器里面跑(tomcat、jetty都可以)
- 内嵌的Jetty目前不支持JSP
- Undertow不支持jsp
- jsp自定义错误页面不能覆盖spring boot默认的错误页面
springboot不同的版本下,模板引擎下可能引用了SpringBoot-start-web依赖,目前下面示例的2.0.2需要单独引用web依赖
四、FreeMarker Demo
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
五、Thymeleaf Demo
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
六、JSP Demo
<dependency>
<groupId>org.springframework.boot></groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
模板引擎FreeMarker
创建一个FreeMarker模板引擎项目,具体步骤如下:
1.创建项目的时候,选择下图中的三项

2.控制层代码
@Controller
@RequestMapping("/web")
public class WebController {
private static final Logger logger = LoggerFactory.getLogger(WebController.class);
@RequestMapping("/index")
public String index(ModelMap map) {
logger.info("这里是WebController...");
map.put("title", "fremarker测试成功!");
return "index"; //注意,不要在最前面加上/,linux下面会出错
}
}
- 项目的静态文件和模板存放位置,如下图

FreeMarker默认将静态文件存放在resources目录下的static目录,模板文件默认存放templates目录下
4.FreeMarker模板文件默认后缀名为.ftl
5.html文件示例代码
<!DOCTYPE html>
<html>
<head lang="en">
<title>Spring Boot Demo - FreeMarker</title>
<link href="/css/index.css" ref="stylesheet"/>
</head>
<body>
<center>
<img src="/images/logo.png"/>
<h1 id="title">${title}</h1>
</center>
</body>
<script type="text/javascript" src="/webjars/jquery/3.3.1-1/jquery.min.js"></script>
<script>
$(function(){
$('#title').click(function(){
alert("点击了");
});
});
</script>
</html>
6.pom.xml文件中引入jquery,如下
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1-1</version>
</dependency>
7.测试结果,如下图

模板引擎Thymeleaf
此处只介绍模板引擎Thymeleaf项目的基本创建和使用
1.创建Thymeleaf项目,如下图

2.Controller代码,如下
@Controller
@RequestMapping("/web")
public class WebController {
private static final Logger logger = LoggerFactory.getLogger(WebController.class);
@RequestMapping("/index")
public String index(ModelMap map) {
logger.info("这里是WebController...");
map.put("title", "thymeleaf测试成功!");
return "index"; //注意,不要在最前面加上/,linux下面会出错
}
}
3.资源目录如下

4.模板文件默认为html,示例index.html代码如下
<!DOCTYPE html>
<html>
<head lang="en">
<title>Spring Boot Demo - FreeMarker</title>
<link href="/css/index.css" ref="stylesheet"/>
</head>
<body>
<center>
<img src="/images/logo.png"/>
<h1 id="title" th:text="${title}"></h1>
</center>
</body>
<script type="text/javascript" src="/webjars/jquery/3.3.1-1/jquery.min.js"></script>
<script>
$(function(){
$('#title').click(function(){
alert("点击了...");
});
});
</script>
</html>
5.引用jquery
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1-1</version>
</dependency>
6.测试

模板殷勤jsp
spring boot是不建议使用jsp的,详情见上面的模板引擎选择
具体创建步骤如下
1.创建项目,如下图


创建完成后,项目结构如下

ServletInitializer.java的作用和web.xml作用一样,是启动项目的入口,此适用于web3.0及其以上的规范,web2.0规范的还是需要web.xml作为web项目启动的入口
2.pom.xml中引入jsp相关jar包,如下图
<!-- jsp解析 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- jstl支持 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
3.controller示例代码
@Controller
@RequestMapping("/web")
public class WebController {
private static final Logger logger = LoggerFactory.getLogger(WebController.class);
@RequestMapping("/index")
public String index(ModelMap map) {
logger.info("这里是WebController...");
map.put("title", "jsp测试成功!");
return "index"; //注意,不要在最前面加上/,linux下面会出错
}
}
4.在webapp目录下,创建WEB-INF/templates目录,在新建的目录下,创建index.jsp,如下图

5.application.properties做如下配置
spring.mvc.view.prefix=/WEB-INF/templates/
spring.mvc.view.suffix=.jsp
6.引入静态资源文件,如下图

7.启动测试项目

8.打成war包,本地启动



错误处理
一、错误的处理
方法一:Spring Boot将所有的错误默认隐射到/error,实现ErrorController
@Controller
@RequestMapping("error")
public class ErrorTestController implements ErrorController{
private static final Logger logger = LoggerFactory.getLogger(ErrorTestController.class);
@Override
public String getErrorPath() {
logger.info("出错啦!进入自定义出错容器");
return "error/error";
}
@RequestMapping
public String error() {
return getErrorPath();
}
}
添加异常页面

运行并试结果

方法二:添加自定义的错误页面
2.1 html静态页面:在/resources/public/error/下定义
如添加404页面:resources/public/error/404.html页面,中文注意页面编码
2.2 模板引擎页面:在templates/error下定义
如添加5xx页面:templates/error/5xx.ftl
注:templates/error/ 这个的优先级比较 resources/pubilc/error/ 高
步骤如下
- 删除ErrorTestController.java
- html静态页面:在/resources/public/error/下定义
如添加404页面:resources/public/error/404.html页面,中文注意页面编码 模板引擎页面:在templates/error下定义
如添加5xx页面:templates/error/5xx.ftl测试404,如下图

测试error,如请求一下controller中的test
@Controller
@RequestMapping("/web")
public class WebController {
private static final Logger logger = LoggerFactory.getLogger(WebController.class);
@RequestMapping("/index")
public String index(ModelMap map) {
logger.info("这里是WebController...");
map.put("title", "fremarker测试成功!");
return "index"; //注意,不要在最前面加上/,linux下面会出错
}
@RequestMapping("/test")
public String test(ModelMap map) {
logger.info("这里是error test...");
throw new RuntimeException("测试异常!");
}
}

方法三:使用注解@ControllerAdvice
- 创建异常处理类,示例代码如下
package com.cht.error.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
/**
* 自定义异常
* @author 16694
*
*/
@ControllerAdvice
public class BizException {
private static final Logger logger = LoggerFactory.getLogger(BizException.class);
/**
* 统一异常处理
* @param exception
* @return
*/
@ExceptionHandler({RuntimeException.class})
@ResponseStatus(HttpStatus.OK)
public ModelAndView processException(RuntimeException exception) {
logger.info("自定义异常处理-RuntimeException...");
ModelAndView mv = new ModelAndView();
mv.addObject("roncooException",exception.getMessage());
mv.setViewName("error/500");
return mv;
}
/**
* 统一异常处理
* @param exception
* @return
*/
@ExceptionHandler({Exception.class})
@ResponseStatus(HttpStatus.OK)
public ModelAndView processException(Exception exception) {
logger.info("自定义异常处理-Exception...");
ModelAndView mv = new ModelAndView();
mv.addObject("roncooException",exception.getMessage());
mv.setViewName("error/500");
return mv;
}
}
- 创建500.html页面,500.html页面示例代码
<!DOCTYPE html>
<html>
<head lang="en">
<title>Spring Boot Demo - error</title>
</head>
<body>
<h1>error-系统错误,请联系后台管理员</h1>
错误信息:${roncooException}
</body>
</html>
- 启动 测试


Servlet、Filters、Listeners
一、Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能需要用到servlet、filter、listener等等
二、在spring boot中的三种实现方式
方法一、通过注册ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean获得控制
1.servlet
如下图,创建测试servlet

代码如下
package com.cht.servletFilterListenter.util.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义servlet
* @author 16694
*
*/
public class CustomServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet get method");
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet post method");
resp.getWriter().write("servlet test...");
}
}
启动类中,注入servlet bean,代码如下
package com.cht.servletFilterListenter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import com.cht.servletFilterListenter.util.filter.CustomFileter;
import com.cht.servletFilterListenter.util.servlet.CustomServlet;
@SpringBootApplication
public class Demo62ServletFilterListernerApplication {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new CustomServlet(),"/roncoo");
}
public static void main(String[] args) {
SpringApplication.run(Demo62ServletFilterListernerApplication.class, args);
}
}
启动测试


2.filter
自定义filter代码如下
package com.cht.servletFilterListenter.util.filter;
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;
/**
* 自定义filter
* @author 16694
*
*/
public class CustomFileter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init filter...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter filter...");
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("destroy filter...");
}
}
启动类注入filter bean代码
@Bean
public FilterRegistrationBean filterRegistrationBean() {
// return new FilterRegistrationBean(new CustomFileter(),servletRegistrationBean()); //只拦截servletRegistrationBean
return new FilterRegistrationBean(new CustomFileter()); //拦截全部
}
启动 测试



3.listener
创建CustomListener,代码如下
package com.cht.servletFilterListenter.util.listerner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 自定义 listener
* @author 16694
*
*/
public class CustomListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed...");
}
}
启动类注册listener bean,代码如下
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
return new ServletListenerRegistrationBean(new CustomListener());
}
注册servlet、filter和listener的另一种方法
package com.cht.servletFilterListenter;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import com.cht.servletFilterListenter.util.filter.CustomFileter;
import com.cht.servletFilterListenter.util.listerner.CustomListener;
import com.cht.servletFilterListenter.util.servlet.CustomServlet;
@SpringBootApplication
//public class Demo62ServletFilterListernerApplication{
public class Demo62ServletFilterListernerApplication implements ServletContextInitializer{
/* @Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new CustomServlet(),"/roncoo");
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
// return new FilterRegistrationBean(new CustomFileter(),servletRegistrationBean()); //只拦截servletRegistrationBean
return new FilterRegistrationBean(new CustomFileter()); //拦截全部
}
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
return new ServletListenerRegistrationBean(new CustomListener());
} */
public static void main(String[] args) {
SpringApplication.run(Demo62ServletFilterListernerApplication.class, args);
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addServlet("customServlet", new CustomServlet()).addMapping("/roncoo");//此处路径少了“/”,启动会报错
servletContext.addFilter("customFileter", new CustomFileter()).addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true,"customFileter");//拦截指定bean
// servletContext.addFilter("customFileter", new CustomFileter()).addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true);//拦截所有
servletContext.addListener(new CustomListener());
}
}
主要代码如下

方法三、在SpringBootApplication 上使用 @ServletComponentScan 注解后,直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,推荐第三种方法
启动类代码
package com.cht.servletFilterListenter;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import com.cht.servletFilterListenter.util.filter.CustomFileter;
import com.cht.servletFilterListenter.util.listerner.CustomListener;
import com.cht.servletFilterListenter.util.servlet.CustomServlet;
@SpringBootApplication
@ServletComponentScan
//public class Demo62ServletFilterListernerApplication{
public class Demo62ServletFilterListernerApplication{
//public class Demo62ServletFilterListernerApplication implements ServletContextInitializer{
/* @Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new CustomServlet(),"/roncoo");
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
// return new FilterRegistrationBean(new CustomFileter(),servletRegistrationBean()); //只拦截servletRegistrationBean
return new FilterRegistrationBean(new CustomFileter()); //拦截全部
}
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
return new ServletListenerRegistrationBean(new CustomListener());
} */
public static void main(String[] args) {
SpringApplication.run(Demo62ServletFilterListernerApplication.class, args);
}
/*@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addServlet("customServlet", new CustomServlet()).addMapping("/roncoo");//此处路径少了“/”,启动会报错
servletContext.addFilter("customFileter", new CustomFileter()).addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true,"customFileter");//拦截指定bean
// servletContext.addFilter("customFileter", new CustomFileter()).addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true);//拦截所有
servletContext.addListener(new CustomListener());
}*/
}
servlet代码
package com.cht.servletFilterListenter.util.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义servlet
* @author 16694
*
*/
@WebServlet(urlPatterns="/roncoo",name="customServlet")//此处路径少了“/”,启动会报错
public class CustomServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet get method");
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet post method");
resp.getWriter().write("servlet test...");
}
}
filter代码
package com.cht.servletFilterListenter.util.filter;
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;
/**
* 自定义filter
* @author 16694
*
*/
@WebFilter(urlPatterns="/*")//拦截全部
public class CustomFileter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init filter...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter filter...");
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("destroy filter...");
}
}
listener代码
package com.cht.servletFilterListenter.util.listerner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* 自定义 listener
* @author 16694
*
*/
@WebListener
public class CustomListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed...");
}
}
启动测试

CORS支持
一、Web开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS等等
CORS和JSONP相比
- JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
- 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获取数据,比起JSONP有更好的错误处理。
- JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝多数现代浏览器都已经支持了CORS
浏览器支持情况
Chrom 3+
Pirefox 3.5+
Opera 12+
Safari 4+
Internet Explorer 8+
二、在spring MVC中可以配置全局规则,也可以使用@CrossOrigin注解进行细粒度的配置。
全局配置
@Configuration
public class CustomCorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
//http://localhost:8080下的api下的所有请求都允许跨域
registry.addMapping("/api/**").allowedOrigins("http://localhost:8080");
}
};
}
}
局部跨域配置
定义方法啊
@RestController
@RequestMapping("/api")
public class ApiController {
@CrossOrigin(origins="http://localhost:8080")
@RequestMapping("/get")
public HashMap<String, Object> get(@RequestParam String name){
HashMap<String, Object> map = new HashMap<>();
map.put("title", "跨域");
map.put("name",name);
return map;
}
}
测试js
$(function(){
$('#title').click(function(){
//alert("点击了");
$.ajax({
url:"http://localhost:8081/api/get",
type:"POST",
data:{
name:"测试"
},
success:function(data,status,xhr){
console.log(data);
alert(data.name);
}
});
});
});
测试效果

文件上传
一、Spring Boot 默认使用spring MVC包装好的解析器进行上传
二、添加代码
js
<form method="POST" enctype="multipart/form-data" action="/file/upload">
文件:<input type="file" name="roncooFile"/>
<input type="submit" value="上传"/>
</form>
controller
@Controller
@RequestMapping("/file")
public class FileController {
private static final Logger logger = LoggerFactory.getLogger(FileController.class);
@RequestMapping("/upload")
@ResponseBody()
public String upload(@RequestParam("roncooFile") MultipartFile file) {
if(file.isEmpty()) {
return "文件为空";
}
//获取文件名
String fileName = file.getOriginalFilename();
logger.info("上传的文件名为:" + fileName);
//获取文件后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//文件上传路径
String filePath = "d:/roncoo/education/";
//解决中文问题,linux下中文路径,图片显示有问题
// fileName = UUID.randomUUID() + suffixName;
File dest = new File(filePath + fileName);
//检测目录是否存在
if(!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
//spring封装的方法上传
file.transferTo(dest);
return "上传成功!";
} catch (Exception e) {
e.printStackTrace();
}
return "上传失败!";
}
}
测试

三、配置
当上传的文件过大时,会报如下错误
Resolved exception caused by Handler execution: org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (20992233) exceeds the configured maximum (10485760)
spring boot 提供如下上传文件配置
# MULTIPART (MultipartProperties)
# Whether to enable support of multipart uploads.默认支持上传
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk. Values can use the suffixes "MB" or "KB" to indicate megabytes or kilobytes, respectively.#支持文件写入磁盘
spring.servlet.multipart.file-size-threshold=0
# Intermediate location of uploaded files.上传文件的临时目录(linux系统下配置成如:“/temp”,windows下配置成如:“D:/temp”)
spring.servlet.multipart.location=
# Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or kilobytes, respectively.最大支持文件大小
spring.servlet.multipart.max-file-size=5MB
# Max request size. Values can use the suffixes "MB" or "KB" to indicate megabytes or kilobytes, respectively.最大支持请求大小
spring.servlet.multipart.max-request-size=10MB
# Whether to resolve the multipart request lazily at the time of file or parameter access.
spring.servlet.multipart.resolve-lazily=false
SQL
使用关系型数据库-JdbcTemplate
一、配置数据源
嵌入式数据库的支持:Spring Boot 可以自动配置 H2,HSQL and Derby 数据库,不需要提供任何的链接URL,只需要加入相应的 jar 包,Spring Boot 可以自动发现装配
<!-- 数据库 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
mysql 配置
#mysql配置
spring.datasource.url=jdbc:mysql://localhost/study
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
注:
1. 可以不指定driver-class-name,spring boot会自动识别url。
2. 数据连接池默认使用tomcat-jdbc
连接池配置:spring.datasource.tomcat.*
二、JdbcTemplate模板
//自动注册
@Autowired
private JdbcTemplate jdbcTemplate;
三、 脚本
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '注释',
`user_name` varchar(30) NOT NULL COMMENT '用户名',
`password` varchar(50) DEFAULT NULL COMMENT '密码',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`height` double DEFAULT NULL COMMENT '身高',
`date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '生日',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMNET='用户表';
四、实体类
/**
* 实体类
*/
public class RoncooUser(){
private int id;
private String name;
private Date createTime;
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Date getCreateTime(){
return createTime;
}
}