Spring Boot适合来开发WEB应用程序,因为它提供了很多便利,如支持嵌入式HTTP服务器;提供了starter来管理依赖,快速开始,例如使用spring-boot-starter-web开始web应用程序开发,使用spring-boot-starter-webflux开始响应式web开发。
Spring Web MVC框架
在SpringMVC框架中,使用@Controller或@RestController标注请求处理器,使用@RequestMapping标志请求处理方法,例如:
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
Spring MVC自动配置
Spring Boot的自动配置特性在开发Spring MVC WEB应用时相当方便。
默认情况下,Spring Boot自动配置提供的东东:
- ContentNegotiatingViewResolver和BeanNameViewResolver
- 支持静态资源
- Converter, GenericConverter, and Formatter
- HttpMessageConverters
- MessageCodesResolver
- 支持静态index.html
- 支持自定义Favicon
- ConfigurableWebBindingInitializer
如果上面的东东并不能满足你,你还可以:
- 如果你想在上面自动配置的基础上,扩展其他功能,如interceptors, formatters, view controllers等,你可以通过@Configuration标注一个WebMvcConfigurer来扩展,但是注意不能标注@EnableWebMvc。
- 如果你想在上面自动配置的基础上,实现RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver,你可以通过@Configuration标注一个WebMvcRegistrationsAdapter来实现,但是注意不能标注@EnableWebMvc。
- 如果你想要完全控制权,那你就需要@EnableWebMVC来标注前面配置类。
HttpMessageConverters
HttpMessageConverters用来转换响应消息,例如把请求处理方法返回的对象直接转换成JSON或XML。
如果你需要自定义转换器,可以这样做:
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
自定义JSON序列化器和反序列化器
如果你使用Jackson来序列化和反序列JSON数据,你可能希望自定义JsonSerializer和JsonDeserializer,Spring Boot提供了一个@JsonComponent注解可以使自定义更加简单。
@JsonComponent可以直接使用在JsonSerializer、JsonDeserializer和KeyDeserializer实现类上,也可以使用在外部类上,例如:
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;
@JsonComponent
public class Example {
public static class Serializer extends JsonSerializer<SomeObject> {
// ...
}
public static class Deserializer extends JsonDeserializer<SomeObject> {
// ...
}
}
MessageCodesResolver
MessageCodesResover用于为绑定错误生成错误码。
静态内容
默认情况下,静态资源放在/static、/public、/resources目录下,Spring MVC使用ResoucesHttpRequestHandler来处理静态资源,你可以重写WebMvcConfigurer的addResourceHandlers来自定义ResoucesHttpRequestHandler。
默认情况下,静态资源映射到/**,你可以通过spring.mvc.static-path-pattern属性重写,示例:
spring.mvc.static-path-pattern=/resources/**
同样可以通过spring.resources.static-locations自定义静态资源的位置,示例:
spring.resources.static-locations=/icon/
如果你的应用最终打包成webjar,则不要使用webapp目录,因为很多打包工具在打包jar的时候会忽略该目录。
欢迎页
默认的欢迎页是index.html,如果index.html不存在,则查找index模板文件
自定义favicon
favicon.icon文件直接放在静态资源目录下。
路径匹配和内容协商
使用/projects/spring-boot的URL可能不会发送Accept请求头,因此需要通过特殊的手段传递请求内容类型,传统是通过后缀的形式,如/projects/spring-boot.json表示请求json格式内容,但是Spring Boot禁止这种形式映射,因此还要另想办法。使用请求参数传递类型,如/projects/spring-boot?format=json,Spring Boot支持这种方式,同时支持自定义参数名、注册MIME类型等,示例:
spring.mvc.contentnegotiation.favor-parameter=true
# We can change the parameter name, which is "format" by default:
# spring.mvc.contentnegotiation.parameter-name=myparam
# We can also register additional file extensions/media types with:
-types.markdown=text/markdown
如果你特别喜欢后缀形式也是可以的,但是需要你配置,示例:
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true
更安全的做法是只针对一些后缀开启,示例:
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
# You can also register additional file extensions/media types with:
# -types.adoc=text/asciidoc
ConfigurableWebBindingInitializer
SpringMVC使用WebBindingInitializer来初始WebDataBinder,如果你创建你自己的ConfigurableWebBindingInitializer @Bean则会自动应用。
模板引擎
Spring Boot自动配置支持下面这几个模板引擎:
- FreeMarker
- Groovy
- Thymeleaf
- Mustache
当你使用上述模板引擎,并采用自动配置时,模板文件放在src/main/resources/templates。
异常处理
@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}
在上面的例子中,如果Controller抛出异常则会返回CustomErrorType的JSON表示,Controller为AcmeController所在包的类。
自定义错误页
如果你想为一个特定的状态码返回一个错误页面,比如404,你可以在/public/error目录下添加404.html文件。文件名必须是状态码,或状态码的掩码。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
使用FreeMarker模板引擎的错误页面,5xx表示处理所有500错误码。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftlh
+- <other templates>
对于更复杂的映射,你可以实现ErrorViewResolver接口,示例
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
Spring HATEOAS
Spring Boot提供了对Spring HATEOAS的自动配置支持,HATEOAS用于超媒体。
CORS
局部配置跨域访问可以直接使用@CrossOrigin注解,全局配置跨域访问可以通过注册一个WebMvcConfigurer Bean,并实现其addCorsMapping方法,如下:
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}