SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

下一篇[未完待續]

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

英文原文:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features-developing-web-applications
GitHub:https://github.com/jijicai/Spring/tree/master/spring-boot

29.1.6、歡迎頁

Spring Boot 同時支持靜態和模板化歡迎頁面。它首先在配置的靜態內容位置中查找 index.html 文件。如果沒有找到,則查找 index 模板。如果找到其中之一,它將自動用作應用程序的歡迎頁面。

29.1.7、自定義 favicon

Spring Boot 在配置的靜態內容位置和類路徑的根目錄中查找 favicon.ico(按這個順序)。如果存在這樣的文件,它將自動用作應用程序的 favicon。

29.1.8、路徑匹配與內容協商(Content Negotiation)

Spring MVC 可以通過查看請求路徑並將其與應用程序中定義的映射(例如,Controller 方法上的 @GetMapping 註解)匹配,將傳入的 HTTP 請求映射到處理程序。

Spring Boot 默認選擇禁用後綴模式匹配,這意味著“GET/projects/spring-boot.json”之類的請求將不會與 @GetMapping("/projects/spring-boot") 映射匹配。這被認為是 Spring MVC 應用程序的最佳實踐。這個特性在過去對於沒有發送正確的“Accept”請求頭的 HTTP 客戶端非常有用;我們需要確保向客戶端發送正確的 Content Type。如今,內容協商更加可靠。

還有其他方法可以處理不一致地發送正確的“Accept”請求頭的 HTTP 客戶端。不用後綴匹配,我們可以使用查詢參數來確保像“GET/projects/spring-boot?format=json”這樣的請求會被映射到 @GetMapping("/projects/spring-boot"):

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

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:spring.mvc.contentnegotiation.media-types.markdown=text/markdown

如果你理解這些注意事項,並且仍然希望應用程序使用後綴模式匹配,則需要以下配置:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

spring.mvc.contentnegotiation.favor-path-extension=truespring.mvc.pathmatch.use-suffix-pattern=true

或者,與其打開所有後綴模式,不如只支持註冊的後綴模式更安全。

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

spring.mvc.contentnegotiation.favor-path-extension=truespring.mvc.pathmatch.use-registered-suffix-pattern=true# You can also register additional file extensions/media types with:# spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc

29.1.9、ConfigurableWebBindingInitializer

Spring MVC 使用 WebBindingInitializer 為特定請求初始化 WebDataBinder。如果你創建自己的 ConfigurableWebBindingInitializer @Bean,則 Spring Boot 會自動配置 Spring MVC 來使用它。

29.1.10、模板引擎

除了 REST web 服務,你還可以使用 Spring MVC 來提供動態 HTML 內容。Spring MVC 支持多種模板技術,包括:Thymeleaf、FreeMarker 和 JSPs。另外,許多其他的模板引擎還包括它們自己的 Spring MVC 集成。

Spring Boot 包括對以下模板引擎的自動配置支持:

(1)FreeMarker(https://freemarker.apache.org/docs/ )

(2)Groovy(http://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html#_the_markuptemplateengine )

(3)Thymeleaf(https://www.thymeleaf.org/ )

(4)Mustache(https://mustache.github.io/ )

提示:如果可能,應避免使用 JSPs。在將它們與嵌入式 servlet 容器一起使用時,有幾個已知的限制。

當你使用這些具有默認配置的模板引擎之一時,你的模板將自動從 src/main/resources/templates 中獲取。

提示:根據你運行應用程序的方式,IntelliJ IDEA 對類路徑的排序是不同的。在 IDE 中從主方法運行應用程序的順序與使用 Maven 或 Gradle 或從其打包的 jar 運行應用程序的順序不同。這可能會導致 Spring Boot 無法在類路徑上找到模板。如果遇到此問題,可以在 IDE 中重新排序類路徑,以將模塊的類和資源放在第一位。或者,你可以配置模板前綴來搜索類路徑上的每個模板目錄,如下所示:classpath*:/templates/。

29.1.11、錯誤處理

默認情況下,Spring Boot 提供了一個 /error 映射,它以合理的方式處理所有錯誤,並在 servlet 容器中將其註冊為“global”錯誤頁。對於機器客戶端,它生成一個 JSON 響應,其中包含錯誤、HTTP狀態和異常消息的詳細信息。對於瀏覽器客戶端,有一個“whitelabel”錯誤視圖,它以 HTML 格式呈現相同的數據(要對其進行自定義,請添加一個解析為 error 的 View)。若要完全替換默認行為,則可以實現 ErrorController 並註冊該類型的 bean 定義,或者添加 ErrorAttributes 類型的 bean 來使用現有機制,但替換內容。

提示:BasicErrorController 可以用作自定義 ErrorController 的基類。如果要為新內容類型添加處理程序(默認情況下是專門處理 text/html,併為其他所有內容提供回退),這一點特別有用。為此,擴展 BasicErrorController,添加一個帶有 products 屬性的 @RequestMapping 的公共方法,並創建一個新類型的 bean。

你還可以定義一個用 @ControllerAdvice 註解的類來定製 JSON 文檔,以返回特定的控制器和/或異常類型,如下面示例所示:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

@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 表示。

自定義錯誤頁

如果要顯示給定狀態碼的自定義 HTML 錯誤頁,則可以將文件添加到 /error 文件夾。錯誤頁可以是靜態 HTML(即添加到任何靜態資源文件夾下)或使用模板生成。文件名應該是確切的狀態碼或序列掩碼。

例如,要將 404 映射到靜態 HTML 文件,文件夾結構如下:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

src/ +- main/     +- java/     |   +      +- resources/         +- public/             +- error/             |   +- 404.html             +- 

要使用 FreeMarker 模板映射所有 5xx 錯誤,文件夾結構如下:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

src/ +- main/     +- java/     |   +      +- resources/         +- templates/             +- error/             |   +- 5xx.ftl             +- 

對於更復雜的映射,還可以添加實現 ErrorViewResolver 接口的 bean,如下面所示:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

public class MyErrorViewResolver implements ErrorViewResolver {    @Override    public ModelAndView resolveErrorView(HttpServletRequest request,            HttpStatus status, Map model) {        // Use the request or status to optionally return a ModelAndView        return ...    }}

你還可以使用常規的 Spring MVC 特性,比如 @ExceptionHandler 方法和 @ControllerAdvice。然後,ErrorController 將拾取任何未處理的異常。

在 Spring MVC 之外映射錯誤頁

對於不使用 Spring MVC 的應用程序,可以使用 ErrorPageRegistrar 接口直接註冊 ErrorPages。這種抽象直接與底層的嵌入式 servlet 容器一起工作,即使沒有 Spring MVC DispatcherServlet。

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

@Beanpublic 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"));    }}

如果使用最終由 Filter 處理的路徑註冊 ErrorPage(這在某些非 Spring web 框架中很常見,如 Jersey 和 Wicket),則必須將 Filter 顯示註冊為 ERROR 調度器,如下面示例所示:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

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

注意,默認的 FilterRegistrationBean 不包括錯誤調度器類型。

注意:當部署到 servlet 容器時,Spring Boot 使用其錯誤頁過濾器將帶有錯誤狀態的請求轉發到相應的錯誤頁。如果尚未提交響應,則只能將請求轉發到正確的錯誤頁面。默認情況下,WebSphere Application Server 8.0 及更高版本在成功完成 servlet 服務方法後提交響應。你應該通過將 com.ibm.ws.webcontainer.invokeFlushAfterService 設置為 false 來禁用此行為。

29.1.12、Spring HATEOAS

如果你開發了一個使用超媒體的 RESTful API,那麼 Spring Boot 為 Spring HATEOAS 提供了自動配置,它可以很好地與大多數應用程序一起工作。自動配置取代了使用 @EnableHypermediaSupport 的需要,並註冊了許多 bean 來簡化基於超媒體的應用程序的構建,包括一個 LinkDiscoverers(用於客戶端支持)和一個 ObjectMapper(配置為正確地將響應封入所需的表示)。ObjectMapper 是通過設置不同的 spring.jackson.* 屬性來定製的,或者如果存在的話,可以使用 Jackson2ObjectMapperBuilder 來定製。

你可以使用 @EnableHypermediaSupport 來控制 Spring HATEOAS 的配置。注意,這樣做會禁用前面描述的 ObjectMapper 定製。

29.1.13、CORS 支持

跨源資源共享(CORS)是由大多數瀏覽器實現的 W3C 規範,它允許你靈活地指定什麼樣的跨域請求被授權,而不是使用一些不太安全和不太強大的方法,如 IFRAME 或 JSONP。

從版本 4.2 開始,Spring MVC 支持 CORS。在 Spring Boot 應用程序中使用帶有 @CrossOrigin 註解的控制器方法 CORS 配置不需要任何特定的配置。全局 CORS 配置可以通過使用自定義的 addCorsMappings(CorsRegistry) 方法註冊 WebMvcConfigurer bean 來定義,如下面示例所示:

SpringBoot中文參考指南(2.1.6)29.1.13、CORS 支持

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

下一篇[未完待續]


分享到:


相關文章: