刚开始学习,不知道如何入手,可以根据官方提供的demo进行学习。如:
https://spring.io/guides/gs/rest-service/ ,可下载源码查看,有一个大致的了解。
环境准备:
JDK1.8及以上、Maven3.2+
对于编辑器,推荐使用IntelliJ IDEA,创建工程时有引导,可选择需要的spring组件,包括spring web、spring cloud xxx等等,直接生成对应的pom.xml文件,很方便。当然eclipse也很好,用了eclipse很多年,用IDEA真的很不习惯。不过IDEA创建工程的引导真的很棒,如下图创建完工程就可以直接运行了。
由于是学习,我们还是一步步来操作。
1. 创建一个maven工程,pom.xml如下:
4.0.0
com.kevin
spring-boot-study
0.0.1-SNAPSHOT
spring-boot-study
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.1.6.RELEASE
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
可以看出依赖比以往的spring工程简单了很多,我们来看看spring-boot-starter-web到底是什么?
从上图看到spring-web、spring-mvc、spring-beans…是不是很熟悉、很亲切,是不是就是我们传统spring web工程的依赖包。这说明spring-boot-starter-xxx会对需要的依赖包进行封装,引入它就会自动引入需要的依赖包,而且不用再考虑版本冲突的,jar包丢失或者重复的问题,这就是spring-boot的精髓之一。
另外我们可以从上图中发一个依赖spring-boot-starter-tomcat,这就是spring-boot内置的tomcat,不需要我们再去下载和配置tomcat,这也是spring-boot的精髓之一。
2. 编写启动类 SpringBootStudyApplication.java,类名自定义,但是必须放在最根目录。
package com.kevin.springbootstudy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootStudyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudyApplication.class, args);
}
}
就是一个main方法,使用SpringApplication.run()启动应用(依次启动spring组件和tomcat)。关键是注解@SpringBootApplication,看看@SpringBootApplication做了哪些事情:
@SpringBootConfiguration定义当前类为配置类,
@EnableAutoConfiguration自动加载配置,
@ComonentScan 扫描该类所在的包下所有需要管理的类,相当于之前的
,这也是为什么启动类需要放在根目录的原因。
也可以给@SpringBootApplication指定属性,如exclude(哪些包不需要扫描)、scanBasePackages(指定扫描包)
3. 直接运行启动类(SpringBootStudyApplication.java),可以看到直接启动了一个tomcat,端口默认8080,最前面还有一个banner信息(后面讲如何自定义)
4. 创建Greeting,定义基础属性和构造方法,注意这里用final,赋值后不能修改
package com.kevin.springbootstudy.model;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
5. 创建HelloController.java,提供api
counter使用的并发包,数量递增,不存在并发问题
注解@RestController是由@Controller @ResponseBody(将结果以字符串形式返回)组合而成
package com.kevin.springbootstudy.controller;
import com.kevin.springbootstudy.model.Greeting;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@Controller
public class HelloController {
private final static String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/hello")
public Greeting hello(@RequestParam(value = "name", defaultValue = "World") String name){
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
6. 启动服务(SpringBootStudyApplication.java)进行测试
访问http://127.0.0.1:8080/hello,返回:{"id":1,"content":"Hello, World!"}
访问http://127.0.0.1:8080/hello?name=Kevin,返回:{"id":2,"content":"Hello, Kevin!"}
7. 编写测试类
使用MockMvc模拟网络请求,分别写两个测试方法,一个不带参数,一个带参数,匹配返回的结果是否达到预期
jsonPath(expression) 将返回的结果按表达式进行匹配
jsonPath("$.content") 返回的结果从头开始,获取属性为content的数据
测试需要用到MockMvcRequestBuilders 的一些静态方法,可直接引入是代码更简洁
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
package com.kevin.springbootstudy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTests {
@Autowired
private MockMvc mockMvc;
@Test
public void noParamTest() throws Exception{
this.mockMvc.perform(get("/hello")).andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.content").value("Hello, World!"));
}
@Test
public void paramTest() throws Exception{
this.mockMvc.perform(get("/hello").param("name", "Kevin")).andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.content").value("Hello, Kevin!"));
}
}
测试都正常,可以发现搭建一个简单的能够提供api访问的工程,使用spring boot明显快速简便很多,真正的是开箱即用。