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>
