javascript
spring 2.2 改进_Spring 4中@ControllerAdvice的改进
spring 2.2 改進(jìn)
在Spring 4的許多新功能中,我發(fā)現(xiàn)了@ControllerAdvice的改進(jìn)。 @ControllerAdvice是@Component的特殊化,用于定義適用于所有@RequestMapping方法的@ ExceptionHandler,@ InitBinder和@ModelAttribute方法。 在Spring 4之前,@ ControllerAdvice在同一Dispatcher Servlet中協(xié)助了所有控制器。 在Spring 4中,它已經(jīng)發(fā)生了變化。 從Spring 4開始,可以將@ControllerAdvice配置為支持定義的控制器子集,而仍可以使用默認(rèn)行為。
@ControllerAdvice協(xié)助所有控制器
假設(shè)我們要創(chuàng)建一個錯誤處理程序,該錯誤處理程序?qū)⑾蛴脩麸@示應(yīng)用程序錯誤。 我們假設(shè)這是一個基本的Spring MVC應(yīng)用程序,其中Thymeleaf作為視圖引擎,并且我們有一個ArticleController具有以下@RequestMapping方法:
package pl.codeleak.t.articles;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("article") class ArticleController {@RequestMapping("{articleId}")String getArticle(@PathVariable Long articleId) {throw new IllegalArgumentException("Getting article problem.");} }如我們所見,我們的方法拋出了一個假想異常。 現(xiàn)在,使用@ControllerAdvice創(chuàng)建一個異常處理程序。 (這不僅是Spring中處理異常的可能方法)。
package pl.codeleak.t.support.web.error;import com.google.common.base.Throwables; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.ModelAndView;@ControllerAdvice class ExceptionHandlerAdvice {@ExceptionHandler(value = Exception.class)public ModelAndView exception(Exception exception, WebRequest request) {ModelAndView modelAndView = new ModelAndView("error/general");modelAndView.addObject("errorMessage", Throwables.getRootCause(exception));return modelAndView;} }該課程不是公開的,因為它不是公開的。 我們添加了@ExceptionHandler方法,該方法將處理所有類型的Exception,它將返回“錯誤/常規(guī)”視圖:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head><title>Error page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><link href="../../../resources/css/bootstrap.min.css" rel="stylesheet" media="screen" th:href="@{/resources/css/bootstrap.min.css}"/><link href="../../../resources/css/core.css" rel="stylesheet" media="screen" th:href="@{/resources/css/core.css}"/> </head> <body> <div class="container" th:fragment="content"><div th:replace="fragments/alert :: alert (type='danger', message=${errorMessage})"> </div> </div> </body> </html>為了測試該解決方案,我們可以運行服務(wù)器,或者(最好)使用Spring MVC Test模塊創(chuàng)建一個測試。 由于我們使用Thymeleaf,因此可以驗證渲染的視圖:
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = {RootConfig.class, WebMvcConfig.class}) @ActiveProfiles("test") public class ErrorHandlingIntegrationTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void before() {this.mockMvc = webAppContextSetup(this.wac).build();}@Testpublic void shouldReturnErrorView() throws Exception {mockMvc.perform(get("/article/1")).andDo(print()).andExpect(content().contentType("text/html;charset=ISO-8859-1")).andExpect(content().string(containsString("java.lang.IllegalArgumentException: Getting article problem.")));} }我們期望內(nèi)容類型為text / html,并且視圖包含帶有錯誤消息HTML片段。 但是,它并不是真正的用戶友好型。 但是測試是綠色的。
使用上述解決方案,我們提供了一種處理所有控制器錯誤的通用機(jī)制。 如前所述,我們可以使用@ControllerAdvice:做更多的事情。 例如:
@ControllerAdvice class Advice {@ModelAttributepublic void addAttributes(Model model) {model.addAttribute("attr1", "value1");model.addAttribute("attr2", "value2");}@InitBinderpublic void initBinder(WebDataBinder webDataBinder) {webDataBinder.setBindEmptyMultipartFiles(false);} }@ControllerAdvice協(xié)助選定的控制器子集
從Spring 4開始,可以通過批注(),basePackageClasses(),basePackages()方法來自定義@ControllerAdvice,以選擇控制器的一個子集來提供幫助。 我將演示一個簡單的案例,說明如何利用此新功能。
假設(shè)我們要添加一個API以通過JSON公開文章。 因此,我們可以定義一個新的控制器,如下所示:
@Controller @RequestMapping("/api/article") class ArticleApiController {@RequestMapping(value = "{articleId}", produces = "application/json")@ResponseStatus(value = HttpStatus.OK)@ResponseBodyArticle getArticle(@PathVariable Long articleId) {throw new IllegalArgumentException("[API] Getting article problem.");} }我們的控制器不是很復(fù)雜。 如@ResponseBody批注所示,它將返回Article作為響應(yīng)正文。 當(dāng)然,我們要處理異常。 而且我們不希望以text / html的形式返回錯誤,而是以application / json的形式返回錯誤。 然后創(chuàng)建一個測試:
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = {RootConfig.class, WebMvcConfig.class}) @ActiveProfiles("test") public class ErrorHandlingIntegrationTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void before() {this.mockMvc = webAppContextSetup(this.wac).build();}@Testpublic void shouldReturnErrorJson() throws Exception {mockMvc.perform(get("/api/article/1")).andDo(print()).andExpect(status().isInternalServerError()).andExpect(content().contentType("application/json")).andExpect(content().string(containsString("{\"errorMessage\":\"[API] Getting article problem.\"}")));} }測試是紅色的。 我們能做些什么使其綠色? 我們需要提出另一條建議,這次僅針對我們的Api控制器。 為此,我們將使用@ControllerAdvice注解()選擇器。 為此,我們需要創(chuàng)建一個客戶或使用現(xiàn)有注釋。 我們將使用@RestController預(yù)定義注釋。 帶有@RestController注釋的控制器默認(rèn)情況下采用@ResponseBody語義。 我們可以通過將@Controller替換為@RestController并從處理程序的方法中刪除@ResponseBody來修改我們的控制器:
@RestController @RequestMapping("/api/article") class ArticleApiController {@RequestMapping(value = "{articleId}", produces = "application/json")@ResponseStatus(value = HttpStatus.OK)Article getArticle(@PathVariable Long articleId) {throw new IllegalArgumentException("[API] Getting article problem.");} }我們還需要創(chuàng)建另一個將返回ApiError(簡單POJO)的建議:
@ControllerAdvice(annotations = RestController.class) class ApiExceptionHandlerAdvice {/*** Handle exceptions thrown by handlers.*/@ExceptionHandler(value = Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ResponseBodypublic ApiError exception(Exception exception, WebRequest request) {return new ApiError(Throwables.getRootCause(exception).getMessage());} }這次運行測試套件時,兩個測試均為綠色,這意味著ExceptionHandlerAdvice輔助了“標(biāo)準(zhǔn)” ArticleController,而ApiExceptionHandlerAdvice輔助了ArticleApiController。
摘要
在以上場景中,我演示了如何輕松利用@ControllerAdvice批注的新配置功能,希望您像我一樣喜歡所做的更改。
參考資料
- SPR-10222
- @RequestAdvice注釋文檔
翻譯自: https://www.javacodegeeks.com/2013/11/controlleradvice-improvements-in-spring-4.html
spring 2.2 改進(jìn)
總結(jié)
以上是生活随笔為你收集整理的spring 2.2 改进_Spring 4中@ControllerAdvice的改进的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二楼用英语怎么读 二楼的英语的读音
- 下一篇: MicroProfile OpenAPI