spring boot Deploy Web Application之Spring MVC
Spring Web MVC框架(通常简称为“ Spring MVC”)是一个丰富的“模型视图控制器” Web框架。Spring MVC使您可以创建特殊的@Controller或@RestController Bean来处理传入的HTTP请求。使用@RequestMapping注解将控制器中的方法映射到HTTP。
简单使用@RestController
@RestController注解中包含@Controller和@ResponseBody这两个注解,因此返回数据以json的数据返回。
创建一个项目,结构如下:
spring的配置application.yml中添加如下代码:
只需要配置相关服务的相关端口。
创建一个controller类,如下(IndexController.java):
返回对象:UserVos.java
启动项目之后,就可以通过访问拿到数据:
Spring mvc自动配置
Spring Boot为Spring MVC提供了自动配置,在大多数应用程序中都能很好地工作。
自动配置在Spring的默认值之上添加了以下功能:
- 包含ContentNegotiatingViewResolver和BeanNameViewResolver beans
- 支持服务静态资源,包括支持WebJars
- 自动注册Converter,GenericConverter和Formatter beans
- 提供HttpMessageConverters
- 自动注册MessageCodesResolver
- 静态index.html支持
- 自定义Favicon支持
- 自动使用ConfigurableWebBindingInitializer bean
如果想保留Spring Boot MVC功能并想要添加其他MVC配置(拦截器,格式化程序,视图控制器和其他功能),则可以添加自己的@Configuration WebMvcConfigurer类型的类,但没有@EnableWebMvc。 如果希望提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明一个WebMvcRegistrationsAdapter实例以提供此类组件。
如果要完全控制Spring MVC,则可以添加用@EnableWebMvc注释的自己的@Configuration。
HttpMessageConverters
Spring MVC使用HttpMessageConverter接口转换HTTP请求和响应,开箱即用中包含了默认值。例如,可以将对象自动转换为JSON(通过使用Jackson库)或XML(通过使用Jackson XML扩展(如果可用)或通过使用JAXB(如果Jackson XML扩展不可用))。默认情况下,字符串以UTF-8编码。
通过上面的描述,我们可以有如下流程图:
context中存在的所有HttpMessageConverter bean都将添加到转换器列表中。可以用相同的方式覆盖默认转换器
自定义json序列化和反序列化
如果使用Jackson来序列化和反序列化JSON数据,则可能要编写自己的JsonSerializer和JsonDeserializer类。 自定义序列化程序通常是通过模块向Jackson进行注册的,但是Spring Boot提供了替代的@JsonComponent注解,这使得直接注册Spring Bean更加容易。
可以直接在JsonSerializer或JsonDeserializer实现上使用@JsonComponent注解。 您也可以在包含序列化器/反序列化器作为内部类的类上使用它。
ApplicationContext中的所有@JsonComponent bean都会自动向Jackson注册。因为@JsonComponent用@Component进行元注解,所以通常的组件扫描规则适用。
Spring Boot还提供了JsonObjectSerializer和JsonObjectDeserializer基类,这些基类在序列化对象时为标准Jackson版本提供了有用的替代方法。
MessageCodesResolver
Spring MVC有一个生成错误代码以从绑定错误中呈现错误消息的策略:MessageCodesResolver。如果设置spring.mvc.message-codes-resolver.format属性PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE。
静态内容
默认情况下,Spring Boot从类路径中的/static(或/public或/resources或/META-INF/resources)目录或ServletContext的根目录中提供静态内容,它使用Spring MVC中的ResourceHttpRequestHandler,以便可以通过添加自己的WebMvcConfigurer并覆盖addResourceHandlers方法来修改该行为。
在独立的Web应用程序中,还启用了容器中的默认Servlet,并将其用作后备,如果Spring决定不处理,则从ServletContext的根目录提供内容。在大多数情况下,这不会发生(除非修改默认的MVC配置),因为Spring始终可以通过DispatcherServlet处理请求。
默认情况下,资源被映射到/**上,但是可以使用spring.mvc.static-path-pattern属性来调整它。 例如,将所有资源迁移到/resources/**可以实现如下目标:
spring:
mvc:
static-path-pattern: /resources/**
spring.mvc.static-path-pattern=/resources/**
还可以通过使用spring.resources.static-locations属性(用目录位置列表替换默认值)来自定义静态资源位置。root Servlet context path“/”也自动添加为location。
除了前面提到的“标准”静态资源位置,Webjar内容也有特殊情况。如果/webjars/**中有路径的任何资源都从jar文件提供
以Webjars格式打包
如果应用程序打包为jar,则不要使用src/main/webapp目录。尽管此目录是一个通用标准,但它仅适用于war打包,如果生成jar,大多数构建工具都会默默忽略该目录
Spring Boot还支持Spring MVC提供的高级资源处理功能,允许使用案例,例如缓存清除静态资源或对Webjars使用版本无关的URL。
要对Webjars使用版本无关的URL,请添加webjars-locator-core依赖项,然后声明Webjar.以jQuery为例,添加“ /webjars/jquery/jquery.min.js”将得到“ /webjars/jquery/x.y.z/jquery.min.js”。 其中x.y.z是Webjar版本。
如果使用JBoss,则需要声明webjars-locator-jboss-vfs依赖关系,而不是webjars-locator-core。否则,所有Webjar都解析为404。
要使用缓存清除,以下配置可为所有静态资源配置缓存清除解决方案,从而有效地添加内容哈希,例如
配置如下:
spring:
resources:
chain:
strategy:
content:
enabled: true
paths: /**
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
借助为Thymeleaf和FreeMarker自动配置的ResourceUrlEncodingFilter。使用JSP时,应该手动声明此过滤器。 当前不自动支持其他模板引擎,但可以与自定义模板 macros/helpers一起使用,以及使用ResourceUrlProvider。
例如,当使用JavaScript模块加载器动态加载资源时,不能重命名文件。 这就是为什么其他策略也受支持并且可以组合的原因。 “固定”策略会在网址中添加静态版本字符串,而不会更改文件名
spring:
resources:
chain:
strategy:
content:
enabled: true
paths: /**
fixed:
enabled: true
paths: /js/lib/
version: v12
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
通过这种配置,位于“/js/lib/”下的JavaScript模块使用固定的版本控制策略(“/v12/js/lib/mymodule.js”),而其他资源仍使用内容版本< link href =“/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css“ />
Spring Boot支持静态和模板欢迎页面。它首先在配置的静态内容位置中查找index.html文件。如果未找到,则寻找索引模板。如果找到任何一个,它将自动用作应用程序的欢迎页面。
路径匹配和内容协商
Spring MVC可以通过查看请求路径并将其与应用程序中定义的映射进行匹配,将传入的HTTP请求映射到处理程序。
Spring Boot默认选择禁用后缀模式匹配,这意味着“GET /projects/spring-boot.json”之类的请求将不会与@GetMapping(“/projects/spring-boot”)映射进行匹配。 这被认为是Spring MVC应用程序的最佳实践。 过去,此功能主要用于未发送正确的“ Accept”请求标头的HTTP客户端。 我们需要确保将正确的内容类型发送给客户端。 如今,内容协商已变得更加可靠。
还有其他处理HTTP客户端的方法,这些方法不能始终发送正确的“ Accept”请求标头。 除了使用后缀匹配,我们还可以使用查询参数来确保将诸如“GET/projects/spring-boot?format=json”之类的请求映射到@GetMapping(“/projects/spring-boot”):
spring:
mvc:
contentnegotiation:
favor-parameter: true
favor-path-extension: true
media-types:
markdown: text/markdown
spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.media-types.markdown=text/markdown
#应用程序使用后缀模式匹配
spring.mvc.contentnegotiation.favor-path-extension=true
模板引擎
除了REST Web服务之外,还可以使用Spring MVC来提供动态HTML内容。Spring MVC支持各种模板技术,包括Thymeleaf,FreeMarker和JSP。另外,许多其他模板引擎包括它们自己的Spring MVC集成。
Spring Boot包括对以下模板引擎的自动配置支持:
- FreeMarker
- Groovy
- Thymeleaf
- Mustache
在默认配置下使用这些模板引擎之一时,将选择的模板
从src/main/resources/templates自动启动
根据运行应用程序的方式,IntelliJ IDEA对类路径的排序方式不同。与使用Maven或Gradle或从打包的jar运行应用程序时,从IDE的main方法运行应用程序的顺序会有所不同。这可能会导致Spring Boot无法在类路径上找到模板。如果遇到此问题,可以在IDE中重新排序类路径,以首先放置模块的类和资源。或者,可以
配置模板前缀以搜索类路径上的每个模板目录,如下所示:classpath *:/templates/
错误处理
默认情况下,Spring Boot提供了一个/error映射,以明智的方式处理所有错误,并且在servlet容器中将其注册为“全局”错误页面。对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“ whitelabel”错误视图以HTML格式呈现相同的数据(要对其进行自定义,请添加一个可解决错误的视图)。要完全替换默认行为,可以实现ErrorController并注册该类型的bean定义,或者添加类型为ErrorAttributes的bean以使用现有机制,但替换其内容。
BasicErrorController可以用作自定义ErrorController的基类。如果要为新的内容类型添加处理程序(默认是专门处理text/html并为其他所有内容提供后备功能),这将特别有用。为此,请扩展BasicErrorController,添加一个具有@RequestMapping且具有Produces属性的公共方法,并创建一个新类型的bean。
还可以定义一个用@ControllerAdvice注释的类,以自定义JSON文档以针对特定的控制器and/or异常类型返回,如以下示例所示:
@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);
}
}
在前面的示例中,如果YourException由同一包中定义的控制器引发作为AcmeController,使用CustomErrorType POJO的JSON表示代替ErrorAttributes表示形式
提供CORS
跨域资源共享(CORS)是大多数浏览器实施的W3C规范,可以灵活地指定授权哪种类型的跨域请求,而不是使用某些安全性和功能较弱的方法,例如IFRAME或JSONP。
从4.2版开始,Spring MVC支持CORS。 在Spring Boot应用程序中将控制器方法CORS配置与@CrossOrigin批注一起使用时,不需要任何特定的配置。 可以通过使用自定义的addCorsMappings(CorsRegistry)方法注册WebMvcConfigurer bean来定义全局CORS配置,如以下示例所示:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}