创建项目
首先创建一个快速的maven项目:
然后使用idea将其打开。
打开pom。
在其中添加parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
关于这个parent:
<name>Spring Boot Starter Parent</name>
<description>Parent pom providing dependency and plugin management for applications
built with Maven</description>
它提供了一些默认的maven配置以及dependency-management
,让你在引入其他依赖的时候不用输入版本号。
我们再引入web和test依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
最后写启动类:
@SpringBootApplication
public class SpringbootStarter {
public static void main(String[] args) {
SpringApplication.run(SpringbootStarter.class,args);
}
}
启动项目:
关注一下tomcat的端口号:
如果出现这个error page就说明springboot启动成功了。
springmvc
我们试一下springmvc是否可行,不过我们不要视图了,返回一个字符串就行了。
package com.ocean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class SpringbootStarter {
public static void main(String[] args) {
SpringApplication.run(SpringbootStarter.class,args);
}
@GetMapping("/greeting")
public String greeting(){
return "hello springboot!";
}
}
这就ok了。
但是,困惑很多。
比如tomcat在哪里?springmvc怎么生效的?(在以后的文章中讲)
单元测试
我们可以通过代码来向DispatcherServlet
发送http请求。
package com.ocean;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest
@RunWith(SpringRunner.class)
public class GreetingControllerTest {
@Autowired
WebApplicationContext applicationContext;
MockMvc mockMvc;
@Before
public void before() {
mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();
}
@Test
public void testGreetingFromController() throws Exception {
MvcResult mvcResult
= mockMvc.perform(MockMvcRequestBuilders.get("/greeting").accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}
}
这里@RunWith
将junit执行类修改为SpringRunner
,而SpringRunner
是Spring测试类SpringJUnit4ClassRunner
的别名。
另一个@SpringBootTest
注解功能强大。它可以提供默认的ContextLoader
,自定义webEnvironment
等。我们后续会详细讲。
我们用WebApplicationContext
来模拟ServletContext
环境。
我们使用MockMvc
发起请求并对响应进行验证。
结果:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /greeting
Parameters = {}
Headers = {Accept=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.ocean.SpringbootStarter
Method = public java.lang.String com.ocean.SpringbootStarter.greeting()
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8], Content-Length=[17]}
Content type = application/json;charset=UTF-8
Body = hello springboot!
Forwarded URL = null
Redirected URL = null
Cookies = []
hello springboot!
我们来更改web环境,然后完全模拟请求的发送。
package com.ocean;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import java.net.URL;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
public class GreetingControllerTest {
@LocalServerPort
private int port;
private URL base;
@Autowired
private TestRestTemplate template;
@Before
public void before() throws Exception {
this.base = new URL("http://localhost:" + port + "/greeting");
}
@Test
public void getGreeting() {
ResponseEntity<String> response = template.getForEntity(base.toString(),
String.class);
System.out.println(response.getBody());
}
}
修改webEnvironment
,使用内嵌容器,提供真实的Servlet
环境。其端口号在容器启动的时候是随机的,但是运行时会通过@LocalServerPort
找到。
应用监控
我们可以使用http端点来监控应用程序,如健康状况、应用信息等。
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
springboot默认的端点有程序的审计信息、运行环境、健康信息、度量信息等等。
如果是一个web应用,还有heapdump,返回hprof堆转储文件;logfile,返回日志文件内容等等。
我们查看一些应用的健康状况:
UP表示应用在线。
你也可以查看springboot提供的所有bean。不过你先要暴露所有端点。在application.yml
中配置:
management:
endpoints:
web:
exposure:
include: "*"
发送请求:
由此我们看到了springboot中的部分bean。
但是,对于这些对外暴露的端点,我们最好提供一定的保护。
加入spring security依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置应用保护:
package com.ocean;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests()
.anyRequest()
.hasRole("ADMIN")
.and()
.httpBasic();
}
}
其中EndpointRequest.toAnyEndpoint()
表示匹配所有的端点,然后需要ADMIN
角色才能访问,同时开启httpBasic()
认证。
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: when_authorized
roles: ADMIN
spring:
security:
user:
name: ocean
password: 123456
roles: ADMIN
在application.yml
中配一个测试用户,他就是ADMIN
角色,并且明确指出health的details信息需要认证才能看到:
springboot初体验就到这里了。