摘要:異常拋出但是看一下報錯信息,發現并不是我們期待的一個錯誤的狀態碼,而是。所以,我們需要全局異常處理,層拋出異常,直接處理,返回狀態碼,而不將異常拋給控制器。異常捕獲后,修改測試,期待狀態碼為,。
控制器測試
還是上次數據不能為空的問題,寫到了C層測試。
先寫一行測試代碼,先期待一個200,但是我們是知道的,因為沒有學科類別,這肯定會拋出異常,我們就是想看看Spring捕獲這個異常之后給出的反饋是什么狀態碼。
@Test public void saveTest() throws Exception { logger.debug("基礎測試數據準備"); MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory(); String json = JSON.toJSONString(measurementUnitCategory); this.mockMvc.perform(post(baseUrl) .header(xAuthKey, xAuthToken) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(json)) .andExpect(status().isOk()); }
測試一下,果然,控制臺報錯。
異常拋出但是看一下報錯信息,發現并不是我們期待的一個錯誤的狀態碼,而是200。同時下面還有異常拋出。
這說明Spring為我們拋出了這個DataIntegrityViolationException異常,但是卻沒有幫我們處理,這就需要我們手動處理然后返回給前臺狀態碼。
MockHttpServletResponse: Status = 200 Error message = null Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Application-Context=[application:-1], Content-Type=[application/json;charset=UTF-8], x-auth-token=[1b2b8d9f-3457-4277-879e-2ada48e3599e]} Content type = application/json;charset=UTF-8 Body = {"id":8,"name":"","username":"usersdfdfwef23dfvdfwewef","mobile":"","pinyin":null,"createTime":1528338758059,"updateTime":1528338758059,"status":0,"department":{"id":1,"name":"內蒙古自治區管理部門","code":"","postalCode":"","address":"","legalName":"","legalPhone":"","registrantName":"","registrantPhone":"","registrantTel":null,"registrantMail":"","phone":"","pinyin":"neimengguzishiquguanglibumeng","registerDate":null,"createTime":1528338752423,"updateTime":1528338752423,"status":null,"createUser":null,"departmentType":{"id":1,"name":"管理部門","pinyin":"guanlibumen","createTime":1528338751963,"updateTime":1528338751963,"createUser":null},"district":{"id":1,"districtType":{"id":1,"name":"省","pinyin":"sheng"},"name":"內蒙古自治區","createUser":null,"pinyin":"neimengguzizhiqu","createTime":null,"updateTime":null},"checkAbility":false,"outOfRange":null,"standard":false},"roles":[],"createUser":null,"updateUser":null} Forwarded URL = null Redirected URL = null Cookies = [] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "DISCIPLINE_ID"; SQL statement: insert into measurement_unit_category (id, discipline_id, is_asc) values (null, ?, ?) [23502-194]全局異常處理
理論上我們所有的異常都是由M層拋出,直接捕獲或全局異常處理,是不會將異常拋給控制器的。
所以,我們需要全局異常處理,M層拋出異常,直接處理,返回xx狀態碼,而不將異常拋給控制器。
@RestController // 以rest形式返回異常信息 @ControllerAdvice // 全局異常處理器 public class GlobalExceptionHandler { private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class.getName()); /** * 手動捕獲數據沖突異常,經測試,該異常系由Spring拋出,但未捕獲 * @return HttpStatus.CONFLICT * 沖突錯誤,409 * 參考: * https://stackoverflow.com/questions/37248719/couldnt-catch-dataintegrityviolationexception-with-spring-data-rest */ @ExceptionHandler(value = DataIntegrityViolationException.class) public ResponseEntitydataIntegrityViolationException(HttpServletRequest httpServletRequest, Exception exception) { logger.error("---數據不合法:---Host {} invokes url {} ERROR: {}", httpServletRequest.getRemoteHost(), httpServletRequest.getRequestURL(), exception.getMessage()); return new ResponseEntity<>(new JsonErrorResult(httpServletRequest, exception), HttpStatus.CONFLICT); } }
我這里對狀態碼也不是很熟悉,去StackOverflow上看到一個老哥是和我遇到了一樣的問題,他解決的方案是捕獲異常返回409(沖突),參考原文。
異常捕獲后,修改測試,期待狀態碼為409,Conflict。
@Test public void saveTest() throws Exception { logger.debug("基礎測試數據準備"); MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory(); String json = JSON.toJSONString(measurementUnitCategory); logger.debug("無學科的計量單位類別保存,期待409,沖突狀態碼"); this.mockMvc.perform(post(baseUrl) .header(xAuthKey, xAuthToken) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(json)) .andExpect(status().isConflict()); }
重新運行單元測試,通過。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69677.html
摘要:在本講中,通過一個精簡的項目,著重介紹一些的異常處理技巧。現在,為了快熟實現自定義異常信息處理類,并讓其正常工作,我們可以直接擴展提供的類來定義用戶異常信息處理類。將異常報告封裝到對象中,并回傳給。 能夠正確的處理REST API程序拋出的異常以及返回友好的異常信息是一件非常重要的事情,因為它可以幫助API客戶端正確的對服務端的問題作出正確的響應。這有助于提高REST API的服務質量。Sp...
摘要:挺多人咨詢的,異常處理用切面注解去實現去全局異常處理。全局異常處理類,代碼如下代碼解析如下抽象類是用來處理全局錯誤時進行擴展和實現注解標記的切面排序,值越小擁有越高的優先級,這里設置優先級偏高。 本文內容 為什么要全局異常處理? WebFlux REST 全局異常處理實戰 小結 摘錄:只有不斷培養好習慣,同時不斷打破壞習慣,我們的行為舉止才能夠自始至終都是正確的。 一、為什么要全局...
摘要:定制特定異常返回結果根據官方文檔的例子,可以使用和對特定異常返回特定的結果。下面是用瀏覽器和訪問的結果無輸出注意上方表格的錯誤,產生這個的原因前面已經講過。不過需要注意的是,無法通過設定,由或者容器決定里一律是。 github:https://github.com/chanjarste... 參考文檔: Spring Boot 1.5.4.RELEASE Documentation ...
摘要:和的區別方法注解作用于級別注解為一個定義一個異常處理器類注解作用于整個工程注解定義了一個全局的異常處理器需要注意的是的優先級比高即拋出的異常如果既可以讓標注的方法處理又可以讓標注的類中的方法處理則優先讓標注的方法處理處理中的異常為了方便地展 @ControllerAdvice 和 @ExceptionHandler 的區別 ExceptionHandler, 方法注解, 作用于 Co...
摘要:首先,定義一個存放異常處理函數的類,并使用修飾。修飾的方法的寫法和內的異常處理函數寫法是一樣的。控制生效的范圍注意到,我是這樣編寫注解的它用來限定這些異常處理函數起作用的的范圍。使用的機制,做統一異常處理。 在具體的SSM項目開發中,由于Controller層為處于請求處理的最頂層,再往上就是框架代碼的。因此,肯定需要在Controller捕獲所有異常,并且做適當處理,返回給前端一個友...
摘要:對的配置和行為進行定制修改匹配路由請求規則注冊自定義的和添加靜態資源處理器添加自定義視圖控制器添加自定義方法參數處理器配置消息轉換器清空所有轉換器做一個好人。博客園掘金簡書頭條知乎 一個大的系統,在代碼的復用肯定是必不可少的,它能解決: 統一的響應處理(可以對外提供統一的響應對象包裝) showImg(https://segmentfault.com/img/remote/146000...
閱讀 1848·2021-11-22 15:24
閱讀 1307·2021-11-12 10:36
閱讀 3194·2021-09-28 09:36
閱讀 1837·2021-09-02 15:15
閱讀 2745·2019-08-30 15:54
閱讀 2391·2019-08-30 11:02
閱讀 2392·2019-08-29 13:52
閱讀 3539·2019-08-26 11:53