SpringBoot

1 SpringBoot入门

1.1 传统 Spring 开发的问题

(1)Spring的优点

Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的EnterpriseJavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Ordinary Java Object,POJO)实现了EJB的功能。

(2)Spring的问题

虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。

1.2 SpringBoot简介

1.2.1 什么是Spring Boot

使用Spring开发Java项目,被诟病最多的是项目搭建过程太繁琐,尤其是要找到合适的Spring版本以及需要整合的其他框架的兼容版本,需要花费大量的时间去试错;哪怕找对了所有依赖JAR包,要配置好这些框架,也需要编写不少的配置文件(XML)。

SpringBoot是一个快速搭建Spring项目的脚手架,几乎不需要什么工作量就可以快速整合Spring及其它常用框架,快速构建应用,而而无需考虑包依赖、框架版本和复杂的配置问题。

传统的SSM框架项目的开发过程:

在这里插入图片描述

Spring Boot项目的开发过程

在这里插入图片描述

1.2.2 Spring Boot 的特性

(1)能够快速创建基于 Spring 的应用程序;

(2)简化部署:对于Web项目,Spring内置Web容器,能够直接使用 main 方法启动内嵌的 Tomcat,不需要部署 war 包文件

(4)简化依赖:提供约定的起步依赖(Starter)来简化 Maven 配置

(5)自动化配置,根据项目的 Maven 依赖配置, Spring boot 自动 配置 Spring、 Spring mvc 等

(6)提供了程序的健康检查等功能 ;

(7)可以完全不使用 XML 配置文件,采用注解和Java配置。

1.2.3 Spring Boot 的四大核心功能

(1)自动配置:针对常用的Spring功能及其它框架的整合,SpringBoot提供自动配置。对于不能自动化的少量配置,Spring Boot 提供了统一的配置文件(application.properties / application.yml)(porperties优于yml执行),配置更集中,便于管理。

(2)起步依赖(Starter):Spring Boot 把常用的一组依赖包打包成一个套装,然后加上自动化配置信息,制作成“起步依赖”包。“起步依赖”一方面解决了JAR包版本冲突问题,另一方面极大的简化了配置。

(3)提供 SpringBoot CLI,可以基于命令行进行快速操。

(4)提供Actuator模块:用于观察和监控Spring项目运行状况。

1.2.4 Spring Boot 开发版本推荐

➢ 如果是使用 eclipse,推荐安装 Spring Tool Suite (STS)插件

➢ 如果使用 IDEA 旗舰版,自带了 Spring Boot 插件 ➢ 推荐使用 Maven 3.3+

➢ 推荐使用 Java 8, Spring Boot 2.x 系列需要至少 Java8

1.2.5 体验Spring Boot CLI

以下用一个极端的例子来演示Spring Boot 有多自动化。

搭建一个SpringMVC项目需要的步骤大家都应该心里有数了,但如果使用Spring Boot的命令行,我们就可以什么都不做了。

(1)安装Spring Boot CLI
下载:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#getting-started-installing-the-cli 解压并添加bin路径(如D:\dev\spring-2.2.0.RELEASE\bin)到环境变量Path

(2)编写控制器

@RestController
public class HelloController{
    @GetMapping("/")
    public String hello(){
        return "Hello Spring Boot!";
    }
}

(3)命令行中(cmd)运行

spring run HelloController.java

2 创建SpringBoot工程

2.1 创建Spring Boot 项目

2.1.1 创建的三种方式 (推荐第二种)

(1)直接在Spring官网提供的start页面创建maven项目:https://start.spring.io/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bI424zW7-1666058755514)(SpringBoot.assets/ec7d3f98-50eb-4ad8-98c1-919847bf8d0a.png)]

(2)使用 Idea 提供的 “New Project > Spring Initializr” 菜单向导

在这里插入图片描述

(3)使用Spring Tool Suite(STS)提供的“File > New > Spring Starter Proejct” 菜单向导

在这里插入图片描述

2.1.2 创建第一个SpringBoot项目

(1)添加SpringBoot的起步依赖

​ 1)starter-parent:SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.4.5.RELEASE</version>
</parent>

​ 2)SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>

(2)编写 SpringBoot 启动类

@SpringBootApplication
public class MyFirstBootApplication {
    public static void main(String[] args) {
       SpringApplication.run(MyFirstBootApplication.class);
    }
}

(3)添加控制器类,并运行启动类

@RestController
public class HelloController{
    @GetMapping("/hello")
    public String hello(){
        return "Hello Spring Boot!";
    }
}

注意,上述的 @RequetController 注解 是一个复合注解,代表了 @Controller 和 @ResponseBody,即指定当前控制器方法的返回值会作为响应体直接返回,即对象通常序列化为JSON格式输出。

2.1.3 代码解析

(1)启动类

@SpringBootApplication		//标注SpringBoot的启动类,该注解具备多种功能(@Configuration+@ComponentScan等)。
SpringApplication.run(MyFirstBootApplication.class) //代表运行SpringBoot的程序,参数为SpringBoot启动类对象

(2)项目结构:

static: 存放静态资源,如图片、 CSS、 JavaScript 等

templates:存放 Web 页面的模板文件

application.properties:用于存放程序的各种依赖模块 的配置信息,比如 服务端口,数据库连接配置等

2.2 SpringBoot工程热部署

2.2.1 SpringBoot热部署工具——devtools

我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大的时间。
在这里插入图片描述

在 pom.xml 中添加”devtools“ (如下配置)就可以实现在修改代码后不重启就能生效,我们称之为热部署。

<!--热部署配置-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
</dependency>
2.2.2 IDEA 进行 SpringBoot 热部署失败问题的解决

我们在IDEA中使用SpringBoot的devtools工具时可能会失效。出现这种情况,并不是热部署配置问题,其根本原因是因为 IEDA 默认情况下不会自动编译,需要对 IDEA 进行自动编译的设置,如下:

(1)在设置(Settings)中启用自动编译
在这里插入图片描述
在这里插入图片描述

(2)在维护(Maintenance)中的注册(Registry)中勾选运行时自动编译选项

同时按住 Ctrl + Shift + Alt + / 然后进入Registry ,勾选自动编译并调整延时参数:

​ compiler.automake.allow.when.app.running -> 自动编译

​ compile.document.save.trigger.delay -> 自动更新文件(针对静态文件如JS CSS的更新,将延迟时间减少)

在这里插入图片描述

2.3 SpringBoot 原理分析(重点)

(1)起步依赖原理分析

查看spring-boot-starter-parent的pom文件**,上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递**

(2)分析spring-boot-starter-web

按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml。发现spring-boot-starter-web就是将web开发要使用的 spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。

(3)自动配置原理解析

按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication注解@SpringBootApplication的源码其中, @SpringBootConfiguration:等同于 @Configuration,既标注该类是Spring的一个配置类 @EnableAutoConfiguration:SpringBoot自动配置功能开启

@SpringBootApplication  
public class MyFirstBootApplication {   
    public static void main(String[] args) {   				         
        SpringApplication.run(MyFirstBootApplication.class);                                          }
	}
}

3 SpringBoot的配置文件

使用 Spring Boot 开发项目时,很多配置都是 Spring Boot Starter 默认配置好的,然而在实际开发中,项目的配置需求是灵活多变的,我们经常需要调整这些默认配置。

3.1 Spring Boot 的配置参数

不同于传统开发中每个框架都有自己的配置文件,Spring Boot 提供了统一的配置(application.yml或application.porperties),并通过各种 Starter 套件提供了数百个可以配置的参数,这些配置参数基本可以满足我们日程开发的需要。

3.1.1 Spring Boot 参数的配置方法

Spring Boot提供了多种方式来实现微调配置:如命令行参数、JNDI属性、JVM系统属性、操作系统的环境变量、application配置文件(application.properties 或 application.yml)等等。下面演示最简单的两种配置方式:命令行参数和application配置文件。

创建一个 “spring-boot-starter-web” 项目。

(1)使用命令行参数

SpringBoot项目可以通过“mvn package”打包并通过“java -jar”执行。

在项目根(pom.xml)目录下执行编译和运行:

mvn package
java -jar .\target\demo-0.0.1-SNAPSHOT.jar 

运行时,我们还可以通过命令行参数指定微调配置,例如:启动端口号

java -jar .\target\demo-0.0.1-SNAPSHOT.jar --server.port=9092

**(2)使用aplication.properties **

server.port=9091

(3)使用application.yml(或 application.yaml)

server:
    port:9091

(4)使用外置的application配置文件

进入 target 目录,在 Spring Boot 项目打包的 JAR 旁边添加外置的 application.yml

server:
    port:9093

使用命令启动 JAR

java -jar .\demo-0.0.1-SNAPSHOT.jar 
3.1.2 SpringBoot配置的几种途径和优先级

(1)配置优先级

Spring Boot 项目如果在多个地方配置了相同的参数,则按以下优先级进行加载:

  1. 命令行参数;2) java:comp/env里的JNDI属性;3) JVM系统属性;4) 操作系统环境变量;5) 应用程序以外的application配置文件;6) 打包在应用程序内的application配置文件;7)@PropertySource标注的属性源;8) 默认值。

(2)application配置文件(application.properties和application.yml)可以放置的位置

  1. 外置,应用程序运行目录的/config子目录;2) 外置,应用程序运行目录里;3) 内置,在config包内;4) 内置,在classpath根目录。

3.2 yaml 配置文件简介

yml 或 yaml (Yet Another Markup Language)是一种直观的能够被电脑识别的的数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。YML文件的扩展名可以使用 .yml 或者 .yaml。

yml配置文件的语法

(1)配置普通数据

语法:注意 value 之前有一个空格

key: value

(2)配置对象数据(二级属性)

语法:注意key1前面的空格个数不限定,在yml语法中,相同缩进代表同一个级别

key:
	key1: value1
	key2: value2

示例代码:

person:
	name: haohao
	age: 31
	addr: beijing
 #或者
 person: {name: haohao,age: 31,addr: beijing}

(3)配置Map数据(同上面的对象写法)

person:
	name: haohao
 	age: 31
 	addr: beijing
 	#或者
 person: {name: haohao,age: 31,addr: beijing}

(4)配置数组(List、Set)数据

key:
	- value1
	- value2
	#或者:
key: [value1,value2]

示例:

city:
	- Beijing
	- Tianjin  
city: [Guangzhou, Shenzhen]
#数组对象
person:
	- name: accp
   	  age:  20
 	- name: zhangsan
      age: 21
person: [{name:accp, age:20}, {name:zhangsan, age:21}]

3.3 多环境配置

在实际开发的过程中,我们的项目会经历很多的阶段:开发、测 试、上线。

每个阶段的环境配置也会有所不同。例如:服务器IP和端口、部署路径、数据库连接等。

为了方便在不同的环境之间切换,SpringBoot 提供了多环境配置(Profiles)。

SpringBoot多环境配置具体规则如下:

(1)可以为每个环境创建一个配置文件,命为“application-环境标识.properties“或“application-环境标识.yml“。例如:

总配置文件: application.yml 或 application.properties

开发环境配置文件: application-dev.yml 或 application-dev.properties

测试环境配置文件: application-test.yml 或 application-test.properties

生产环境配置文件: application-product.yml application-product.properties

(2)在总配置文件(application.properties /application.ym)中进行环境的激活

等号右边的值和配置文件的环境标识名一致, 可以更改总配置 文件的配置, 重新运行 Application,查看启动的端口及上下文根。

在总的配置文件application.properties中激活配置文件

#SpringBoot 的总配置文件
#激活开发环境
#spring.profiles.active=dev
#激活测试环境
#spring.profiles.active=test
#激活生产环境
spring.profiles.active=product

3.4 自定义配置

SpringBoot的配置参数定义在 SpringBoot 的核心配置文件中。除了内置的配置项,我们还可以在自定义配置,然后采用特定注解把自定义配置注入到代码中使用。

3.4.1 使用注解@Value注入

通过@Value注解可以将配置文件中的值映射到一个Spring管理的Bean的属性上。

例如:

application.yml配置如下

person:
	name: zhangsan
	age: 18

实体Bean代码如下:

@Controller
public class QuickStartController {
	@Value("${person.name}")
	private String name;
	@Value("${person.age}")
	private Integer age;
	@RequestMapping("/quick")
	@ResponseBody
	public String quick(){
		return "springboot 访问成功! name="+name+",age="+age; }
	}
}
3.4.2 使用 @ConfigurationProperties 注解注入

@ConfigurationProperties注解将一组配置映射成一个对象,注入到托管Bean中。用于一组多个自定义配置项的情况。

通过注解

@ConfigurationProperties(prefix="配置文件中的key前缀")

可以将配置文件中的配置自动与数据实体进行映射,配置项通过实体的set方法注入(数据实体必须提供set方法)

@Controller
@ConfigurationProperties(prefix = "person")
public class QuickStartController {
	private String name;
	private Integer age;
	public void setName(String name) {
		this.name = name;
	} 
	public void setAge(Integer age) {
		this.age = age;
	}
	@RequestMapping("/quick")
	@ResponseBody
	public String quick(){
		return "springboot 访问成功! name="+name+",age="+age;
	}
}

解决警告问题:如果使用@ConfigurationProperties时出现警告,可以添加以下依赖

<!--解决使用 @ConfigurationProperties 注解出现警告问题-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

3.5 日志配置

Java 开源世界有不少日志工具,如:log4j、slf4j、log4j2 和 logback 等。

logback 和log4j2 都是log4j 的升级版,logback 在性能上比Log4j 更加高效,Spring Boot 把LogBack 作为首选的日志记录框架,spring-boot-starter-web 依赖默认包含了logback 的相关依赖。

3.5.1 使用 application.properties设置 logback

通过 application.properties文件,可以实现部分日志配置。

logging.config加载指定位置的日志配置文件
logging.file.max**-history**要保留的存档日志文件的最大数目
logging.file.max**-size**日志文件的最大占用空间,单位为M
logging.level.*设置某个包范围下的日志级别,比如logging.level.org.springframework=DEBUG
logging.pattern.console设置在控制台输出的日志的格式
logging.pattern.dateformat设置在控制台输出的日志的日期格式
logging.pattern.file定义输出到日志文件的日志格式
logging.pattern.level定义日志的输出级别

以下示例,通过application.properties配置logback的日志文件路,并设置对不同范围的日志的等级(输出mapper的调试信息)。

TRACE < DEBUG < INFO < WARN < ERROR

logging.file.path=d:/logback-logs/  		#设置文件输出路径
logging.level.root=WARN              		#根日志输出级别为WARN
logging.level.com.bjpowernode.mapper=DEBUG    #csdn.mapper输出日志为DEBUG
3.5.2 在代码中使用日志输出

通过 LoggerFactory 我们可以得到 日志输出对象 Logger,在业务代码中可以使用 Logger 输出调试信息。

     Logger logger = LoggerFactory.getLogger(this.getClass());
3.5.3 使用logback配置文件

如果需要更详细的日志配置,可以使用单独的日志配置文件

application.yml 中可以通过logging.config 属性指定自定义日志配置文件的位置

logging.config=日志配置文件的位置和名称

默认情况下,Spring Boot 项目可以读取resources 资源目录中特定名字的日志配置文件,如:logback-spring.xml、logback.xml

Spring Boot 推荐使用带有-spring 的文件名作为日志配置,即使用logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--输出日志到控制台-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout>
            <pattern>
                [%p]%d - %msg%n
            </pattern>
        </layout>
    </appender>
    <!--输出日志到文件-->
    <appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>DENY</onMatch>
        </filter>
        <encoder>
            <pattern>
                [%p]%d - %msg%n
            </pattern>
        </encoder>
        <!--指定文件的输出位置-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>
                C:/logs/%d.log
            </fileNamePattern>
        </rollingPolicy>
    </appender>
    <root level="debug">
        <appender-ref ref="consoleLog"></appender-ref>
        <appender-ref ref="fileLog"></appender-ref>
    </root>
</configuration>

4 SpringBoot集成 MyBatis

4.1 SpringBoot 集成 MyBatis

(1)添加起步依赖和驱动包

<!--MyBatis 整合 SpringBoot 的起步依赖-->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>2.0.0</version>
</dependency>
<!--MySQL 的驱动依赖-->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

(2)添加数据源配置信息

在 Springboot 的核心配置文件 application.properties 中配 置数据源

#数据库连接信息
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/myCinema?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
#spring集成Mybatis环境
#实体别名扫描包
mybatis.type-aliases-package=com.bjpowernode.model
#加载Mybatis映射文件
mybatis.mapper-locations=classpath:mappers/*Mapper.xml

(3)向 Spring 托管 Mapper 接口代理对象

在 SpringBoot 中向托管 MyBatis 的Mapper接口代理对象有两种方法

其一:使用@Mapper注解标记Mapper接口,Spring会找到@Mapper标记的接口并生成代理对象托管

@Mapper
public interface CategoryMapper{
	//省略方法
}

其二:在启动类上使用 @MapperScan注解指定Mapper接口所在包,Spring会对其下的接口进行扫描并批量托管

@MapperScan("com.bjpowernode.mapper")
@SpringBootApplication  
public class MyBatisBootApplication {   
	//省略main
}

(4)使用单元测试

创建SpringBoot项目时,一般都会默认带上测试的起步依赖

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

直接创建单元测试,使用@SpringBootTest注解标记测试类,即可实现单元测试功能

@SpringBootTest
public class CategoryMapperTest{
    @Autowired
    private CategoryMapper categoryMapper;
    @Test
    public void test(){
    	categoryMapper.selectAll().forEach(x->System.out.println)   
    }
}

4.2 Spring Boot 事务支持

Spring Boot 使用事务非常简单,底层依然采用的是 Spring 本身提 供的事务管理

(1) 在SpringBoot启动类中使用注解 @EnableTransactionManagement 开启 事务支持 (默认开启)

(2)在访问数据库的 Service 方法上添加注解 @Transactional 即可

//启动类开启事务支持
@SpringBootApplication
@MapperScan(basePackages = "com.bjpowernode.mapper")
@EnableTransactionManagement //开启事务支持(可选项,但@Transactional 必须添加)
public class Application {
}

@Transactional 添加在serviceImpl 开启事务回滚
在这里插入图片描述

4.3 使用 Mybatis 反向工程生成接口、映射文件以及实体 bean

(1)拷贝Mybatis 反向工程配置文件GeneratorMapper.xml到项目的根目录下

(2)根据项目及表的情况,修改 GeneratorMapper.xml 配置

如果使用高版本的MySQL, 驱动类需要变更为: com.mysql.cj.jdbc.Driver;url 后面应该加属性 nullCatalogMeansCurrent=true,否则生成有问题。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 指定连接数据库的JDBC驱动包所在位置,指定到你本机的完整路径 -->
    <classPathEntry location="F:\m2\repository\mysql\mysql-connector-java\8.0.25\mysql-connector-java-8.0.25.jar"/>
    <!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 -->
    <context id="tables" targetRuntime="MyBatis3">

        <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!-- 配置数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/mycinema"
                        userId="root"
                        password="hx12345678">
        </jdbcConnection>

        <!-- 生成model类,targetPackage指定model类的包名,
             targetProject指定生成的model放在接口工程下面-->
        <javaModelGenerator targetPackage="com.powernode.model"
                            targetProject="E:\08.springboot\springboot-dubbo\interface\src\main\java">
            <property name="enableSubPackages" value="false" />
            <property name="trimStrings" value="false" />
        </javaModelGenerator>

        <!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名,
           targetProject指定生成的mapper.xml放在当前工程src -->
        <sqlMapGenerator targetPackage="com.powernode.mapper"                targetProject="src/main/java">
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名,
          targetProject指定生成的Mapper接口放当前工程src目录 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.powernode.mapper"    targetProject="src/main/java">
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>

        <!-- 数据库表名及对应的Java模型类名 -->
        <table tableName="category" domainObjectName="Category"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>
        <table tableName="movie" domainObjectName="Movie"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>

        <table tableName="user" domainObjectName="User"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>


也可以安装插件 Easy Code
在这里插入图片描述

)

(3)在 pom.xml 文件中添加 mysql 反向工程依赖

<!--mybatis代码自动生成插件-->
<plugin>
    <groupId>org.mybatis.generator</groupId>
    	<artifactId>mybatis-generator-maven-plugin</artifactId>
    	<version>1.3.6</version>
    	<configuration>
    	<!--配置文件的位置-->
    	<configurationFile>GeneratorMapper.xml</configurationFile>
    	<verbose>true</verbose>
    	<overwrite>true</overwrite>
    </configuration>
</plugin>

(4)在maven窗口中找到Generator插件启动生成器

(5)如果插件生成的Mapper.xml文件不在resources目录下,则需要手动设置编译目录,否则读取不到映射文件

(idea默认要求mapper文件只能在resources目录)

<resources>
    <resource>
    	<directory>src/main/java</directory>
    	<includes>
    		<include>**/*.xml</include>
    	</includes>
    </resource>
</resources>

5 Spring Boot 前端使用 JSP

5.1 在 pom.xml 文件中配置以下依赖项

SpringBoot 虽然在 starter-web 中嵌入了Tomcat容器,但排除了JSP相关的依赖。对于服务器页面模板基数,SpringBoot 更推崇自己旗下的 Thymeleaf 模板技术,因此没有内置JSP模板依赖,需要使用JSP的开发者,需要添加以下依赖。

<!--如果只是使用 JSP 页面,可以只添加该依赖-->
<dependency>
	<groupId>org.apache.tomcat.embed</groupId>
	<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--如果使用 JSTL 必须添加该依赖-->
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>jstl</artifactId>
</dependency>
<!--如果要使用 servlet 必须添加该以下两个依赖-->
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
	<groupId>javax.servlet.jsp</groupId>
	<artifactId>javax.servlet.jsp-api</artifactId>
	<version>2.3.1</version>
</dependency>

5.2 在 pom.xml 的 build 标签中要配置编译信息。

SpringBoot 要求 jsp 文件必须编译到指定的 META-INF/resources 目 录下才能访问,否则访问不到。在IDEA环境中,我们需要添加以下配置,让IDEA在编译时把 src/main/webapp 下的 jsp 文件输出到 META-INF/resources 目录下。

<!--
SpringBoot 要求 jsp 文件必须编译到指定的 META-INF/resources 目录下才能访问,否则访问不到。其它官方已经建议使用模版技术(后面会课程会单独讲解模版技术)
-->
<resources>
    <resource>
        <!--源文件位置-->
        <directory>src/main/webapp</directory>
        <!--指定编译到 META-INF/resources,该目录不能随便写-->
        <targetPath>META-INF/resources</targetPath>
        <!--指定要把哪些文件编译进去, **表示 webapp 目录及子目录, *.*表示所有文件-->
        <includes>
        	<include>**/*.*</include>
        </includes>
    </resource>
</resources>

5.3 配置 Spring MVC 的视图 展示为 jsp

#SpringBoot 核心配置文件
#指定内嵌 Tomcat 端口号
server.port=8090
#配置 SpringMVC 视图解析器
#其中: / 表示目录为 src/main/webapp
spring.mvc.view.prefix=/WEB-INF/pages/
spring.mvc.view.suffix=.jsp

application.yml 格式的配置文件

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

5.4 在 src/main 下创建一个 webapp 目录

然后在该目录 下新建 index.jsp 页面 如果在 webapp 目录下右键,如果没有创建 jsp 的选项,可以在 Project Structure 中指定 webapp 为 Web Resource Directory

5.5 添加静态资源

客户端资源的默认路径为”resources/static“,可以在其中添加静态资源
在这里插入图片描述

6 添加拦截器

为了统一为应用程序增加一些功能,比如权限控制,统计请求处理时间等功能,可使用基于AOP的拦截器实现。

6.1 创建拦截器

与传统 SpringMVC 项目相同,我们可以通过实现 HandlerInterceptor 接口来编写 Web 拦截器功能

@Component
public class TimerInterceptor  implements HandlerInterceptor {
    long start=0;
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        start=System.currentTimeMillis();
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        long end=System.currentTimeMillis();
        long result=end-start;
         System.out.println("请求资源="+request.getRequestURI()+",使用了="+result+"毫秒");
    }
}

6.2 创建拦截器(springboot)

在SpringBoot项目中,我们可以通过实现 WebMvcConfigurer 接口,对SpringMVC进行进阶的配置,例如配置拦截器。

以下代码基于 WebMvcConfigurer 创建配置类,注册拦截器,配置拦截器的应用路径和排除路径。

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private TimerInterceptor timerInterceptor;
    public void addInterceptors(InterceptorRegistry registry) {
        //使用拦截器的路径表达式,数组
       String[] includePaths={
               "/*"   //应用于所有路径
       };
        //排除拦截器的路径表达式,数组
       String[] excludePaths={
               "/user/login",
               "/error"
       };
       registry.addInterceptor(timerInterceptor)
               .addPathPatterns(includePaths)
               .excludePathPatterns(excludePaths);
    }
}

6.3编写测试代码,测试拦截器是否生效

   @GetMapping("/admin/home")
    @ResponseBody
    public String adminHome(){
        return "admin-home";
    }

    @GetMapping("/user/login")
    @ResponseBody
    public String userLogin(){
        return "login-success";
    }

7. 在Spring Boot 实现 RESTful 控制器

7.1 常用请求方法和SpringMVC对应的注解

(1)HTTP 的请求方式(Request Method)

HTTP的请求方式不仅仅有 GET 和POST,常用的就至少有5种,在规范的前后端分离开发中,开发应该遵循HTTP协议,根据功能提交不同方法的HTTP请求。

GET(SELECT):	从服务器取出资源(一项或多项)。
POST(CREATE):	在服务器新建一个资源。
PUT(UPDATE):	在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):	在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):	从服务器删除资源。

(2)Spring MVC 中对应的控制器注解

注解作用
@RequestMapping支持任意请求方法的请求,可以通过 method 属性指定请求方法
@GetMapping支持Get请求,用于查询数据
@PostMapping只支持Post请求,用于增加数据
@PutMapping只支持Put请求,用于修改数据
@PatchMapping支持此Patch请求,用于修改部分数据(只修改改变的部分属性)
@DeleteMapping只支持Delete请求,删除数据

(3)各种请求方式的测试

浏览器对于同步请求,请求方法往往只能支持“GET”和“POST”,对于其它请求方法(Request Method),我们可以使用 Postman 测试

7.2 认识 RESTful

REST(英文: Representational State Transfer,简称 REST)一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次, REST这个词,是Roy ThomasFielding 在他 2000 年的博士论文中提出的。

详细的RESTful规范,可以参考:

http://www.ruanyifeng.com/blog/2014/05/restful_api.html

究竟什么是RESTful?

简而言之,就是充分利用HTTP请求规范去区分和处理不同的请求。在HTTP协议中,可以用于标识请求的除了URL(请求路径)外,还有Method(请求方法)和请求头信息等等,我们应该充分利用HTTP请求的这些属性去描述后端的服务接口。

特别在前后端分离的项目中,后端使用的是JavaEE服务,前端是静态的HTML和JavaScript,用好RESTful规范,后端的接口才能更容易被前端调用。

下面举一些示例。

GET 	/categories:	列出所有分类
POST 	/categories:	新增一个分类
GET 	/categories/ID:	获取某个指定的分类信息信息
PUT 	/categories/ID:	更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH 	/categories/ID:	更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE 	/categoreis/ID:	删除某个动物园

7.3 RESTful 的优点

➢ 轻量,直接基于 http,不再需要任何别的诸如消息协议 get/post/put/delete 为 CRUD 操作

➢ 面向资源,一目了然,具有自解释性。

➢ 数据描述简单,一般以 xml, json 做数据交换。

➢ 无状态,在调用一个接口(访问、操作资源)的时候,可以不 用考虑上下文,不用考虑当前状态,极大的降低了复杂度。

➢ 简单、低耦合

7.4 RESTful 原则

➢ 增 post 请求、删 delete 请求、改 put 请求、查 get 请求

➢ 请求路径不要出现动词

​ 例如:查询订单接口 /boot/order/1021/1(推荐) /boot/queryOrder/1021/1(不推荐)

➢ 分页、排序等操作,不需要使用斜杠传参数

​ 例如:订单列表接口 /boot/orders?page=1&sort=desc 一般传的参数不是数据库表的字段,可以不采用斜杠

7.5 Spring MVC 对 RESTfulf 风格的支持

SpringMVC 提供了以下几个注解,支持 RESTful 风格的后端服务的开发

  • @RestController 返回 JSON 视图的控制器,即 @Controller+@ResponseBody
  • @PostMapping 接收和处理 Post 方式的请求
  • @DeleteMapping 接收 delete 方式的请求
  • @PutMapping 接收 put 方式的请求
  • @GetMapping 接收 get 方式的请求
  • @ResponseBody 指定控制器的返回值作为响应身体输出(返回 JSON 格式数据)
  • @RequestParam (单个字符接收)
  • @PathVariable (路径传参)获取 url 中的参数,该注解是实现 RESTFul 最主要的一个注解(路径上的占位符的值)
  • @RequestBody (实体类接收)指定控制器的参数接收 JSON 格式数据并需要反序列化(把JSON格式的请求参数反序列化为对象)
  • @ResponseStatus 用于指定响应状态码(如:200、404、500等…)

附:预备知识:使用Java配置Spring

@Repository(dao层)、@Service(业务层) 和 @Controller(控制层)。
在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,
但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。

1 为什么使用Java配置

​ 传统的Spring项目,需要使用XML配置,虽然自定义的组件可以通过注解简化配置,但依然有大量的非自定义组件需要通过XML配置。XML不如Java代码的灵活性(没有良好的语法支持,错误提示和面向对象特性),从Spring 3.x开始,Spring支持并建议使用基于Java代码的配置,全面替代基于XML的配置。Java配置也是后续学习的Spring Boot的推荐配置手段,实际开发中,我们可以结合XML、Java和注解三种配置方式,灵活使用。

1.1 使用“Java配置”实现依赖注入

(1)@Configuration 注解

在 Java 配置中,我们使用@Configuration标记某Java类为配置类,配置类的作用类似于传统的XML配置文件(如:applicationContext.xml)。

@Configuration
public class BeansConfig {
}

(2)@ComponentScan 注解

在配置类中,我们通过 @ComponentScan 注解来指定Spring启动时扫描组件的包范围,它的作用等效于XML配置时的<context:component-scan />。

@Configuration
@ComponentScan(basePackages="com.bjpowernode.service")
public class BeansConfig {
}

在com.bjpowernode.dao包中创建CategoryDao接口及实现类:

@Repository
public class CategoryDaoImpl implements CategoryDao {
    @Override
    public List<String> selectAll() {
        return new ArrayList(){{add("喜剧");add("战争");add("动漫");}};
    }
}

创建Spring容器,这时使用AnnotationConfigApplicationContext类替代传统的ClassPathXmlApplicationContext加载Spring配置类。

ApplicationContext ctx = new AnnotationConfigApplicationContext(BeansConfig.class);
CategoryDao dao = ctx.getBean(CategoryDao.class);
dao.findAll().forEach(x->System.out.println(x));

(3)使用 AnnotationConfigApplicationContext 创建Spring容器

使用XML进行配置时,我们可以通过 ClassPathXmlApplicationContext 来创建Spring容器;

使用Java配置时,我们可以通过通过 AnnotationConfigApplicationContext 来创建Spring容器。

ApplicationContext ctx = new AnnotationConfigApplicationContext(DiConfig.class);
CategoryDao target = ctx.getBean(CategoryDao.class);

(4)@Bean 注解

@Bean用于标记一个方法,Spring会调用这个方法并把方法返回结果作为Bean对象管理起来,它的作用等效于XML配置时的<beans:bean />。@Bean可以通过name属性指定Spring中Bean的对象名,如果不指定,默认Bean的对象名就是工厂方法的方法名。

如果想用一段Java代码来配置一个Bean并交给Spring托管,我们可以用编写一个工厂方法并且给它打上@Bean注解。@Bean注解适用于那些需要被Spring管理的,由外部框架提供而的对象,因为这些类我们无法使用注解进行托管标记。

以下示例为 Spring 配置“数据源”对象和“JdbcTemplate”,实现真实的JDBC数据查询:

@Configuration
@ComponentScan(basePackages = {"com.bjpowernode.dao","com.bjpowernode.service"})
public class BeansConfig {
    @Bean
    public DataSource dataSource() {
        BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
        ds.setUrl("jdbc:mysql://localhost:3306/MyCinema");
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUsername("root");
        ds.setPassword("1234");
        return ds;
    }
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        JdbcTemplate db = new JdbcTemplate();
        db.setDataSource(dataSource);
        return db;
    }
}

让后就可以使用依赖注入为DAO提供JdbcTemplate:

@Repository
public class CategoryDaoImpl implements CategoryDao {
    @Autowired
    private JdbcTemplate db;
    @Override
    public List<Category> findAll() {
        return db.query("select * from Category", 
                BeanPropertyRowMapper.newInstance(Category.class));
    }
}
1.2 使用Java配置实现面向切面

@EnableAspectJAutoProxy注解

用于启用AOP注解配置

@Configuration
@EnableAspectJAutoProxy
@ComponentScan({"com.bjpowernode.service","com.bjpowernode.aspect"})
public class AopConfig {
	public static void main(String[] args) {
		ApplicationContext ctx = new AnnotationConfigApplicationContext(AopConfig.class);
		CategoryBiz target = ctx.getBean(CategoryBiz.class);
		target.findAll();
	}
}
1.3 小结

Java配置往往是和注解配置联合一起使用的,一般情况下:

(1)自己编写的Bean可以通过注解进行配置和依赖注入(例如:@Repository、@Service、@Controller、@Autowired),只要通过Java配置类中的@ComponentScan注解指定Spring启动时的包扫描范围即可;

(2)第三方框架的Bean由于已经打包了,无法注解,则需要通过@Bean注解标记的工厂方法来创建和配置。

2 使用纯 Java 配置来构建简单的SSM项目

2.1 使用Spring的Java配置整合MyBatis

(1)创建Spring配置类,配置模型Bean

import java.io.IOException;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

@ComponentScan(basePackages = "mycinema")
@Configuration
public class BeansConfig {
	//数据源
	@Bean
	public DataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/mycinema");
		dataSource.setUsername("root");
		dataSource.setPassword("1234");
		return dataSource;
	}
	//MyBatis的Session工厂
	@Bean(name = "sqlSessionFactoryBean")
	public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		//如果有基于XML的Mapper配置,则需要该项
//		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//		bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
		bean.setTypeAliasesPackage("mycinema.entity");
		return bean;
	}
	//MyBatis的Mapper扫描器
	@Bean
	public MapperScannerConfigurer mapperScannerConfigurer() {
		MapperScannerConfigurer bean = new MapperScannerConfigurer();
		bean.setBasePackage("mycinema.mapper");
		bean.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
		return bean;
	}
}

(2)编写实体类(Category)和Mapper(CategoryMapper)

public interface CategoryMapper {
	@Select("select * from Category")
	List<Category> findAll();
}

(3)添加单元测试

@ContextConfiguration(classes = BeansConfig.class)	//注意这里使用 Java配置类 加载Spring上下文
@RunWith(SpringJUnit4ClassRunner.class)
public class CategoryMapperTest {
	@Autowired
	private CategoryMapper target;
	@Test
	public void testFindAll() {
		target.findAll().forEach(x->System.out.println(x));
	}
}
2.2 配置声明式事务管理

(1)在Java配置类中添加事务管理器

配置类中添加*** @EnableTransactionManagement 注解***,打开事务管理开关;然后再为Spring添加一个事务管理器Bean。

@ComponentScan(basePackages = "mycinema")
@EnableTransactionManagement
@Configuration
public class BeansConfig {
	//事务管理器
	@Bean
	public PlatformTransactionManager transactionManager(DataSource dataSource) {
		DataSourceTransactionManager tx = new DataSourceTransactionManager();
		tx.setDataSource(dataSource);
		return tx;
	}
	...
}

(2)使用注解配置事务管理

@Service
public class CategoryBizImpl implements CategoryBiz {
	@Autowired
	private CategoryMapper categoryDb;
	@Transactional
	public void deleteAll(int[] ids) {
		for(int id : ids) {
			categoryDb.delete(id);
		}
	}
	......
}
2.3 配置MVC框架和Web应用

(1)使用 WebMvcConfigurerAdapter 配置SpringMVC

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan("mycinema.web")
public class MvcConfig extends WebMvcConfigurerAdapter {
	//配置ViewResolver
	@Bean
	public InternalResourceViewResolver viewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/jsp/");
		viewResolver.setSuffix(".jsp");
		viewResolver.setViewClass(JstlView.class);
		return viewResolver;
	}
	//配置静态资源路径
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//添加对外暴露的的访问路径,用于静态资源
		registry.addResourceHandler("/static/**").addResourceLocations("/static/");
	}
	//配置快速视图映射
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		//免写controller方法快速实现 “/login -> ~/views/login.jsp” 映射
		registry.addViewController("/login").setViewName("login");
        registry.addViewController("/register").setViewName("register");
	}
	//配置文件上传处理
	@Bean
	public MultipartResolver multipartResolver() {	
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setMaxUploadSize(1000000);
		return multipartResolver;
	}
}

(2)使用 WebApplicationInitializer 配置Web应用(替代传统的web.xml)

import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

@Configuration
public class WebInitializer implements WebApplicationInitializer {
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
		ctx.register(BeansConfig.class); // 加载业务Beans配置
		ctx.register(MvcConfig.class); // 加载MVC Beans配置
		ctx.setServletContext(servletContext);
		// 配置编码过滤器
		Filter characterEncodingFilter = new CharacterEncodingFilter("UTF-8");
		servletContext.addFilter("characterEncodingFilter", characterEncodingFilter)
					  .addMappingForUrlPatterns(null, false, "/*");
		// 配置MVC核心Servlet
		Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
		servlet.addMapping("/");
		servlet.setLoadOnStartup(1);
	}
}

3 附录:所需的依赖包pom.xml


	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.8</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.5</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.3</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.6.3</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huangshaohui00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值