SpringBoot(6) - Web(1)

参考:https://docs.spring.io/spring-boot/docs/1.5.17.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications

翻译的官方文档,个人理解,仅供参考。

 

SpringBoot非常适合web应用程序的开发。可以使用Tomcat、Jetty或Undertow创建自包含的HTTP服务器。大部分应用程序会使用spring-boot-starter-web模块来快速开始。依赖如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

1. SpringMVC的自动配置

SpringBoot为SpringMVC提供自动配置,对于大部分应用程序来说都能很好的运行。

自动配置在spring的默认配置上添加以下配置:

  • 包含ContentNegotiatingViewResolver和BeanNameViewResolver
  • 为静态资源提供服务,包括对WebJar的支持
  • 自动注册Converter、GenericConverter、Formatter
  • HttpMessageConverters 
  • 自动注册MessageCodeResolver
  • 提供对静态index.html的支持
  • 自定义Favicon的支持
  • 自动使用ConfigurableWebBindingInitializer

假如保留SpringBoot MVC的特点,并且只是想添加额外的MVC配置(如拦截器、转换器、控制器等),可以添加自定义的WebMvcConfigurerAdapter,通过@Configuration标识,而不需要@EnableWebMvc。

假如想要提供自定义的RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver ,可以声明一个WebMvcRegistrationsAdapter实例提供上述组件。

假如想要完全自定义SpringMVC,可以组合@Configuration和@EnableWebMvc。

 

2. HttpMessageConverters

SpringMVC使用HttpMessageConverters接口转换HTTP请求和响应。Object可以自动转换为JSON(使用Jackson)或XML(使用Jackson XML扩展或JAXB)开箱即用。String默认使用UTF-8编码。

如果需要添加自定义的转换器,可以使用SpringBoot提供的HttpMessageConverters,示例:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration
public class MyConfiguration {
    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<?> additional = ...
        HttpMessageConverter<?> another = ...
        return new HttpMessageConverters(additional, another);
    }
}

任何在上下文中出现的HttpMessageConverter都会被添加进入转换器集合。可以通过这种方式覆盖默认的转换器。

 

3. 自定义JSON序列化和反序列化器

假如使用Jackson去序列化和反序列化JSON数据,你可能会自定义JsonSerializer 和JsonDeserializer 。自定义序列化器一般通过Jackson的一个模块,但是SpringBoot提供一个可供替代的@JsonComponent注解使之更加容易直接注册Spring Bean。

可以在JsonSerializer 或JsonDeserializer实现上直接添加@JsonComponent注解。或者该注解放在一个普通Java类上,该类包含序列化或反序列化器的内部类。示例:

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> {
        // ...
    }
}

在上下文中的所有@JsonComponent注释的bean都会自动注册;因为该注解有@Component注解,所以通过组件扫描也可以注册为bean。

SpringBoot也提供 JsonObjectSerializer和JsonObjectDeserializer基类可以替代标准的Jackson的序列化器。

 

4. 静态资源

默认情况下,Spring Boot将从类路径中的/static(或/public、/resources、/META-INF/resources)目录或ServletContext的根目录中提供静态内容。使用了Spring MVC中的ResourceHttpRequestHandler,可以通过添加自己的WebMvcConfigurerAdapter并覆盖addResourceHandlers方法来修改该行为。

在独立的Web应用程序中,还启用了容器中的默认servlet充当后备,如果Spring决定不去处理它,则从ServletContext的根目录提供内容。 大多数情况下这不会发生(除非修改了默认的MVC配置),因为Spring总是能够通过DispatcherServlet处理请求。

默认情况下,资源通过/**映射,通过spring.mvc.static-path-pattern属性可以进行修改。

示例:修改为加上/resources

spring.mvc.static-path-pattern=/resources/**

还可以使用spring.resources.static-locations属性自定义静态资源位置(将替换默认的目录位置)。 如果执行此操作,默认的欢迎页面检测将切换到自定义位置。 因此,如果启动时在自定义的资源目录下有index.html,它将成为应用程序的主页。

 

除了上面的“标准”静态资源位置之外,还为Webjars内容制作了一个特例。 如果以Webjars格式打包,那么在/webjars/**中具有路径的任何资源都将从jar文件中提供。

提示:假如应用被打包为jar那就不要使用src/main/webapp目录。尽管该目录是一个标准的资源目录,但是它仅在打包为war时起作用;并且在打包为jar时,大部分构建工具会忽略该目录。

 

Spring Boot还支持Spring MVC提供的高级资源处理功能,允许使用缓存破坏静态资源或使用与Webjars无关的URL。

要为Webjars使用版本无关的URL,只需添加webjars-locator依赖项。 然后声明你的Webjar,以jQuery为例,作为“/webjars/jquery/dist/jquery.min.js”,结果为“/webjars/jquery/xyz/dist/jquery.min.js”,其中xyz是Webjar版本。

要使用缓存清除,以下配置将为所有静态资源配置缓存清除解决方案,有效地在URL中添加内容哈希,例如

<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>

配置如下: 

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

提示:由于ResourceUrlEncodingFilter为Thymeleaf和FreeMarker自动配置,因此在运行时在模板中重写资源链接。 您应该在使用JSP时手动声明此过滤器。 目前不会自动支持其他模板引擎,但可以使用自定义模板宏/帮助程序以及ResourceUrlProvider的使用。

 

使用(例如)JavaScript模块加载器动态加载资源时,不能重命名文件。 这就是为什么其他策略也得到支持并可以合并的原因。 “固定”策略将在URL中添加静态版本字符串,而不更改文件名:

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"/>

查看ResourceProperties获取更多可选项。

 

5. 自定义Favicon

Spring Boot在配置的静态内容位置和类路径的根目录中(按此顺序)中查找favicon.ico。 如果存在此类文件,则会自动将其用作应用程序的favicon。

 

6. ConfigurableWebBindingInitializer

Spring MVC使用WebBindingInitializer为特定请求初始化WebDataBinder。 如果创建自定义的ConfigurableWebBindingInitializer @Bean,Spring Boot将自动配置Spring MVC以使用它。

 

7. 错误处理

SpringBoot默认提供一个/error映射处理所有错误,它被注册为servlet容器的全局错误页面。对于机器客户端来说,它将生成一个JSON响应,其中包含错误、HTTP状态和异常消息详细信息。对于浏览器客户端来说,有一个“whitelabel”错误视图,以HTML格式呈现相同的数据(要自定义它,只需添加一个解析为'error'的View)。彻底替换默认的表现形式,可以实现ErrorController并注册为bean,或者只是添加ErrorAttributes类型的bean以使用现有机制但替换内容。

提示:BasicErrorController 可以被用作实现自定义ErrorController的基类。如果要为新内容类型添加处理器,则此功能特别有用(默认情况下是专门处理text/html并为其他所有内容提供后备)。因此,只需要继承BasicErrorController并添加一个有produces 属性的@RequestMapping的public方法,并创建一个新类型的bean。

也可以定义一个@ControllerAdvice为一个特定的controller 和(或)异常类型去返回自定义JSON文档。

@ControllerAdvice(basePackageClasses = FooController.class)
public class FooControllerAdvice 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);
    }
}

上面示例中,如果在与FooController相同的包中定义的控制器抛出YourException,则将使用CustomErrorType POJO的json表示而不是ErrorAttributes。

7.2 自定义错误页面

如果要显示给定状态代码的自定义HTML错误页面,请将文件添加到/error文件夹。 错误页面可以是静态HTML(即添加到任何静态资源文件夹下)或使用模板构建。 文件名应该是确切的状态代码或系列掩码。

例如,去映射404到一个静态页面,目录结构应该像这样:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

使用FreeMarker模板映射5xx错误,目录结构应该像这样:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftl
             +- <other templates>

对于更复杂的映射,你可以添加实现ErrorViewResolver接口的bean:

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 ...
    }
}

也可以使用常规的SpringMVC特性如@ExceptionHandler方法和@ControllerAdvice。ErrorController 会处理所有未被处理的异常。

7.3 映射SpringMVC外部的错误页面

对于不使用Spring MVC的应用程序,可以使用ErrorPageRegistrar接口直接注册ErrorPages。 这种抽象直接与底层的嵌入式servlet容器一起工作,即使没有Spring MVC DispatcherServlet也能工作。

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
    return new MyErrorPageRegistrar();
}
// ...
private static class MyErrorPageRegistrar implements ErrorPageRegistrar {
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }
}

if you register an ErrorPage with a path that will end up being handled by a Filter (e.g. as is common with some non-Spring web frameworks, like Jersey and Wicket), then the Filter has to be explicitly registered as an ERROR dispatcher, e.g.

@Bean
public FilterRegistrationBean myFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new MyFilter());
    ...
    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
    return registration;
}

(the default FilterRegistrationBean does not include the ERROR dispatcher type).

 

8. Spring HATEOAS

如果您正在开发一个使用超媒体的RESTful API,Spring Boot会为Spring HATEOAS提供自动配置,适用于大多数应用程序。 自动配置取代了使用@EnableHypermediaSupport的需要,并注册了许多bean,以便于构建基于超媒体的应用程序,包括LinkDiscoverers(用于客户端支持)和配置为正确编组响应到所需表示的ObjectMapper。 ObjectMapper将基于spring.jackson.*属性。或Jackson2ObjectMapperBuilder bean(如果存在)进行自定义。

可以使用@EnableHypermediaSupport控制Spring HATEOAS的配置。 请注意,这将禁用上述的ObjectMapper自定义描述。

 

9. 跨域的支持

跨域资源共享Cross-origin resouce sharing(CORS)是大多数浏览器实现的W3C规范,允许以灵活的方式指定授权何种类型的跨域请求,而不是使用一些不太安全且功能较弱的方法,如IFRAME或JSONP。

从4.2版本开始,Spring MVC支持开箱即用的CORS。 在Spring Boot应用程序中使用带有@CrossOrigin注解的控制器方法CORS配置不需要任何特定配置(参考controller method CORS configuration)。 可以通过使用自定义的addCorsMappings(CorsRegistry)方法注册WebMvcConfigurer bean来定义全局CORS配置:

@Configuration
public class MyConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值