SpringBoot简单使用
1. SpringBoot简介
解决了在使用Spring/SpringMVC/Mybatis等框架时,需要添加大量的依赖、添加固定的配置的问题,最直接的表现就是不必添加公共的依赖,也不必配置通用的配置。
2. 创建SpringBoot项目
打开https://start.spring.io/
网站,填写创建项目时的选项,点击Generate Project按钮,则可以下载项目。
下载项目后,解压缩,并将项目文件夹剪切到Workspace中(便于后续查找和管理),然后打开Eclipse,通过Import > Existing Maven Projects导入项目。
第一次导入时,项目的结构非常简单,需要等待自动更新及自动下载所依赖的jar包,该过程完成后,项目结构就与普通项目基本一致了,整个过程不需要手动执行任何操作,但是,必须保证当前计算机能够连接到Maven服务器。
如果使用的Eclipse版本是Mars系列的版本,则pom.xml
会提示错误,因为该系列版本的Eclipse内置的配置文件的版本较低,所以提示错误,但是,不影响程序运行!通常推荐使用Oxygen及以上版本。
当导入完成后,在src/main/java
下可以看到生成的包,该包的名称是在网站上创建项目时填写的参数来决定的,同时,在该包下,有SpringbootApplication.java
文件,该类的名称也是根据创建时参数决定的,该类是当前项目的启动类,当需要启动项目时,以普通Java程序的方式运行该类即可,即Run As Java Application。
3. 创建主页
SpringBoot项目推荐将静态资源(html/css/js/图片等)放在src/main/resources
下的static
中:
对static
点击右键,创建HTML文件,默认选中的位置依然是webapp
文件夹,需要手动选中到resources/static
,然后,创建名为index.html
的文件:
然后,打开浏览器,通过http://localhost:8080/
即可访问:
当启动SpringBoot项目时,会启动内置的Tomcat,通过启动日志可以看到:
Tomcat started on port(s): 8080 (http) with context path ''
即项目部署到Tomcat时上下文路径为空的双引号,即空字符串,所以,在访问时,URL中不必添加项目名称。因为每个SpringBoot项目都有自已内置的Tomcat,该Tomcat也只为当前项目服务,所以,SpringBoot认为不需要在部署时添加项目名称!
index.html
是默认显示的页面,在URL中如果没有明确的指定要访问哪个页面,就会自动的查找该页面,如果有,则显示,如果没有,则报告错误。
其它的网页或静态资源也都应该存储在static
或其子级文件夹中!
4. 处理一个请求,转发到JSP页面
假设当前需要处理http://localhost:8080/user/reg
的请求,则与使用Spring MVC相同,先创建UserController
控制器类,并添加必要的注解:
@Controller
@RequestMapping("user")
public class UserController {
}
注意:SpringBoot不需要配置组件扫描(甚至根本就没有Spring的配置文件),默认扫描的位置就是项目的根包,所以,需要被扫描的类必须在根包或其子包中!
暂定目标:发出请求后,能够看到使用jsp制作的登录页面。
首先,需要在pom.xml
中添加新的依赖,因为SpringBoot项目默认是不支持JSP显示的(更推荐的做法是服务器端的控制器都应该响应正文,而不是转发JSP):
<!-- 1.servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 2.jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- 3.jsp支持 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
在src/main/resources
下的application.properties
是SpringBoot项目的配置文件:
需要在这个文件中配置视图解析器的前缀与后缀:
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp
最后,在webapp
下创建WEB-INF
文件夹(SpringBoot项目不需要web.xml
文件,默认也就没有这个文件夹),然后在该文件夹下创建reg.jsp
文件:
在SpringBoot项目中,默认也配置了DispatcherServlet
,且映射的路径是/*
。
所以,处理请求的方法是:
@RequestMapping("reg")
public String showReg() {
return "reg.jsp";
}
然后,打开浏览器,访问http://localhost:8080/user/reg
即可访问。
5. 处理一个请求,并响应正文
仍然请求http://localhost:8080/user/reg
路径,希望得到的响应是一个字符串!
则在原有的处理请求的方法中添加@ResponseBody
注解即可:
@RequestMapping("reg")
@ResponseBody
public String showReg() {
return "这是服务器端的控制器响应的正文";
}
在SpringBoot中,已经将所有能够配置字符编码的位置,全部默认设置为UTF-8,所以,在响应正文时,用到的StringHttpMessageConverter
也是设置了UTF-8编码格式的,所以,能够直接显示中文!
由于当下比较推荐的做法就是:服务器统一都响应正文给客户端,不考虑转发或重定向的做法,所以,可以将控制器类之前的@Controller
注解换成@RestController
注解,并且,删除处理请求的方法之前的@ResponseBody
:
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("reg")
public String showReg() {
return "这是服务器端的控制器响应的正文!!!";
}
}
使用@RestController
表示当前类是一个控制器组件类,具有@Controller
的效果,同时,添加该注解后,当前类中所有处理请求的方法都是响应正文的,相当于每个方法之前都添加了@ResponseBody
。
当然,使用这个注解后,当前类中处理请求的方法就不可能再转发或重定向了,如果一定要转发或重定向,则不可以使用这个注解!
在SpringBoot中,默认也添加了Jackson
,所以,当控制器的方法的返回值是某个SpringMVC默认不识别的类型时,也会调用Jackson
将返回的对象组织为了JSON格式的数据,并修改响应头,响应给客户端。
6. 数据库编程
SpringBoot并不清楚开发人员将使用什么样的数据库或持久层框,所以,在SpringBoot中默认并没有添加这些相关依赖!
所以,需要手动添加这些依赖,当然,也可以在创建项目时就直接勾选:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
如果添加了以上依赖,却不进行任何配置,启动项目时会报告错误,因为一旦添加以上依赖,SpringBoot会自动读取与数据库连接的相关配置,结果读取不到。
所以,需要在application.properties
中添加数据库连接相关的配置:
spring.datasource.url=jdbc:mysql://localhost:3306/22bat_usm?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
其中,spring.datasource.driver-class-name
可以缺省的配置,SpringBoot会自动的从数据库连接的jar包中找到配置文件读取数据库驱动类的类名。
以上各项配置的值如果有误,也不会导致启动时报告错误,因为SpringBoot在启动只是加载以上配置,并没有尝试连接数据库。
接下来,应该检查配置是否正确,可以通过执行单元测试来检查!
在src/test/java
中已经有项目的根包,并有默认存在的测试类:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {
@Test
public void contextLoads() {
}
}
在编写测试方法之前,应该先测试以上contextLoads()
方法,如果运行出错,则表示依赖的jar可能已经损坏,应该删除jar包文件并更新项目,如果运行正常,则编写并执行数据库连接的单元测试:
@Autowired
DataSource dataSource;
@Test
public void getConnection() throws SQLException {
Connection conn = dataSource.getConnection();
System.out.println(conn);
}
当测试连接完成后,就可以开始持久层的开发,例如先开发“注册”功能,直接使用“MyBatis”案例时的数据库与数据表,则首先需要创建User
实体类:
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String phone;
private String email;
private Integer isDelete;
// SET/GET/toString
}
接下来,应该创建UserMapper
持久层接口,并添加抽象方法:
public interface UserMapper {
Integer addnew(User user);
}
为了让框架知道持久层接口在哪里,可以为持久层接口添加@Mapper
注解,但是,这种做法就要求每个持久层接口都必须添加以上注解,可以改为在启动类的声明之前添加@MapperScan
注解,以配置持久层接口所在的包:
@SpringBootApplication
@MapperScan("cn.22bat.springboot.mapper")
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
接下来,需要配置抽象方法匹配的映射,与“MyBatis”案例相同,应该先在src/main/resources
下创建mappers
文件夹,再将持久层配置文件复制到该文件夹中,并进行配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="cn.22bat.springboot.mapper.UserMapper">
<insert id="addnew"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_user (
username, password,
age, phone,
email, is_delete
) VALUES (
#{username}, #{password},
#{age}, #{phone},
#{email}, #{isDelete}
)
</insert>
</mapper>
然后,还需要在application.properties
中配置这些XML映射文件的位置:
mybatis.mapper-locations=classpath:mappers/*.xml
最后,在SpringbootApplicationTests
测试类中编写并执行单元测试:
@Autowired
UserMapper userMapper;
@Test
public void addnew() {
User user = new User();
user.setUsername("SpringBoot");
user.setPassword("6666");
Integer rows = userMapper.addnew(user);
System.out.println("rows=" + rows);
}
7. 整合控制器层与持久层
可以通过控制器接收用户的注册请求,当接收到请求后,控制器自身并不实现插入数据的操作,而是调用持久层对象来完成插入数据,最后,将结果响应给客户端。
首先,应该创建cn.22bat.springboot.util.ResponseResult
类用于向客户端响应JSON数据:
public class ResponseResult<T> {
private Integer state;
private String message;
private T data;
// SET/GET/toString
}
然后,需要在控制器类中添加持久层对象:
@Autowired
private UserMapper userMapper;
调整处理请求的方法:
@RequestMapping("reg")
public ResponseResult<Void> reg(User user) {
// 创建返回值对象
// try {
// 调用持久层对象实现插入用户数据
// 返回值对象:state -> 1
// 返回
// } catch (DuplicateKeyException e) {
// 返回值对象:state -> 2
// 返回值对象:message -> 用户名已被占用
// 返回
// }
}
完成后,打开浏览器,通过http://localhost:8080/user/reg?username=Javascript&password=888888
进行测试。
8. 整合前端界面
直接修改index.html
页面,添加表单,使用AJAX提交请求并处理结果:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>欢迎使用SpringBoot</title>
</head>
<body>
<form id="form-reg" action="handle_reg.do" method="get">
<h1>用户注册</h1>
<p>请输入用户名:</p>
<p><input name="username" /><span id="hint-username"></span></p>
<p>请输入密码:</p>
<p><input name="password" /></p>
<p>请输入年龄:</p>
<p><input name="age" /></p>
<p>请输入手机号码:</p>
<p><input name="phone" /></p>
<p>请输入电子邮箱:</p>
<p><input name="email" /></p>
<p><input id="btn-reg" type="button" value="注册" /></p>
</form>
<script type="text/javascript" src="jquery-3.4.0.min.js"></script>
<script type="text/javascript">
$("#btn-reg").click(function() {
$("#hint-username").html("");
$.ajax({
"url":"user/reg",
"data":$("#form-reg").serialize(),
"type":"post",
"dataType":"json",
"success":function(json) {
if (json.state == 1) {
alert("注册成功!");
} else {
$("#hint-username").html(json.message);
}
}
});
});
</script>