欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中的@ResponseStatus使用

 更新時間:2022年11月16日 10:00:37   作者:lvbinbin2yujie  
這篇文章主要介紹了Spring中的@ResponseStatus使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

@ResponseStatus這個注解確實是個令我頭疼的注解.

先記錄下@ResponseStatus注解的定義. 記錄幾個得到的信息:@ResponseStatus聲明在方法、類上, Spring3.0開始才有的, 三個屬性其中 HttpStatus類型的 value 和 code是一個含義, 默認值就是 服務(wù)器 500錯誤的 HttpStatus.

1. 用法一:標注在@RequestMapping方法上

@Controller
@RequestMapping("/simple")
public class SimpleController {
 
    @RequestMapping("/demo2")
    @ResponseBody
    @ResponseStatus(code = HttpStatus.OK)
    public String demo2(){
        return "hello world";
    }
}

上面說了 code 和 value一個意思,這里我就用code了,相對而言比較喜歡code單詞. 這里作用就是改變服務(wù)器響應(yīng)的狀態(tài)碼 ,比如一個本是200的請求可以通過@ResponseStatus 改成404/500等等.

常見的幾個狀態(tài)碼 HttpStatus.OK 就是 200 , HttpStatus.INTERNAL_SERVER_ERROR 就是 500 等等 ,具體的查看 HttpStatus枚舉 有詳細說明.

實現(xiàn)原理呢,注解底層還是通過設(shè)置 response.setStatus來實現(xiàn).

1.1 在@RequestMapping方法執(zhí)行完成

Spring解析返回值之前,進行了responseStatus設(shè)置

代碼片段位于:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#setResponseStatus

this對象指當前的ServletInvocableHandlerMethod,看到 @ResponseStatus的reason不為空,就調(diào)用response.sendError ; reason為空,就調(diào)用setStatus方法僅僅設(shè)置響應(yīng)狀態(tài)碼.

1.2 記錄下在哪里調(diào)用了這個responseStatus方法 ?

代碼片段位于:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

發(fā)現(xiàn)如果ServletInvocableHandlerMethod的responseReason有值,也就是@ResponseStatus有reason屬性,@RequestMapping方法返回值都不處理了,直接返回;

也就是說只要有@ResponseStatus的 reason屬性標注在 處理器Controller類或者方法上,比如響應(yīng)狀態(tài)碼code設(shè)置為 404,reason設(shè)置為頁面沒找到 ,那 tomcat 展示界面是這樣大概,展示信息就是我們寫的reason屬性.

@ResponseStatus(code=A,reason=B)標注在 @RequestMapping方法上,作用效果與 response.sendError(A,B)是一樣的.

所以,@ResponseStatus我建議啊, 這種方式下使用千萬不要加 reason, 就把@ResponseStatus 當做一個用來改變響應(yīng)狀態(tài)碼的方式!

2. 用法二:標注在@ControllerAdvice中

@ControllerAdvice
@ResponseStatus
public class MyControllerAdvice {
 
    @ExceptionHandler({ArithmeticException.class})
    public ModelAndView fix(Exception e){
        Map map=new HashMap();
        map.put("ex",e.getMessage());
        return new ModelAndView("error",map);
    }
 
}

@ControllerAdvice標注初衷我想就是程序運行過程中發(fā)生異常,對異常如何處理? 而@ResponseStatus標注在@ControllerAdvice類或者該類下的@ExceptionHandler上,區(qū)別大概就是,

原來比如請求程序拋出異常,異常被捕獲,走@ExceptionHandler,正常走完狀態(tài)碼是200.

@ControllerAdvice或者 @ExceptionHandler標注了@ReponseStatus,那走完狀態(tài)碼就是500.

如果你再給@ResponseStatus添加了reason屬性,不管捕獲異常方法咋返回,都是服務(wù)器的錯誤碼捕獲界面,比如上面我的例子,給@ResponseStatus添加reason=”your defined message”.

不管怎么說,下面界面比一大堆異常堆棧信息看起來更簡潔,但我還是不推薦使用誒,原因啊,界面不友好.

3. 用法三:自定義類型的異常添加注解@ResponseStatus

@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR,reason = "not  an error , just info")
public class MyException extends RuntimeException {
    public MyException() {
    }
 
    public MyException(String message) {
        super(message);
    }
}

這樣子,在SpringMvc中如果有某個 @RequestMapping方法拋出該異常, 只要開啟<mvc:annotation-driven/>,異常自動展示的界面都是如下的:

4. SpringMvc異常捕獲方法如下

代碼片段位于:org.springframework.web.servlet.DispatcherServlet#processHandlerException

<mvc:annotation-driven/>注冊了三個HandlerExceptionResolver:ExceptionHandlerExceptionResolver用來處理@ExceptionHandler,而ResponseStatusExceptionResolver是用來處理拋出的異常上標注了@ResponseStatus的解析器.

4.1 ResponseStatusExceptionResolver解析異常方式

代碼片段位于:org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#doResolveException

ex就是@RequestMapping方法拋出自定義的異常,使用工具類解析自定義異常上的@ResponseStatus注解,找到注解就調(diào)用resolveResponseStatus進行響應(yīng)的處理。

protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
            Object handler, Exception ex) {
 
        ResponseStatus responseStatus = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class);
        if (responseStatus != null) {
            try {
                return resolveResponseStatus(responseStatus, request, response, handler, ex);
            }
            catch (Exception resolveEx) {
                logger.warn("Handling of @ResponseStatus resulted in Exception", resolveEx);
            }
        }
        else if (ex.getCause() instanceof Exception) {
            ex = (Exception) ex.getCause();
            return doResolveException(request, response, handler, ex);
        }
        return null;
    }

4.2 ResponseStatusExceptionResolver如何根據(jù)異常上的@ResponseStatus處理響應(yīng)?

代碼片段位于:org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#resolveResponseStatus

獲取了@ReponseStatus的 code reason屬性,reason不為空就 response.sendError(statusCode, reason) ,并且返回一個空的ModelAndView,這里的ModelAndView已經(jīng)沒有意義了,SendError方法簡單來說就是會跳轉(zhuǎn)到web.xml中配置的 錯誤狀態(tài)碼 對應(yīng)的頁面, 沒有配置就是默認的服務(wù)器的那種錯誤界面,且只展示 前面的reason信息,即響應(yīng)類型為text/html .

5. 總結(jié)

不管哪種方式,@ReponseStatus最后都是通過response.setStatus或response.sendError來處理.

如果只是為了返回狀態(tài)碼,建議只使用 @ResponseStatus(code=xxxx)這樣來設(shè)置響應(yīng)狀態(tài)碼;

如果拋出異常呢,不建議@ControllerAdvice里面的 @ResponseStatus和 自定義異常上的 @ResponseStatus一起使用, 按照我的閱讀理解,兩個一起使用肯定是一個生效,而且是 @ControllerAdvice中的@ResponseStatus生效.

場景分析:假設(shè)拋出異常不是我們自定義的異常,我們想改變響應(yīng)的狀態(tài)碼,通過@ExceptionHandler來處理異常,并在@ExceptionHandler方法上也可以設(shè)置@ResponseStatus來達到效果;

假如拋出自定義的異常,自己沒有定義異常處理界面,那在異常上標注@ResponseStatus就可以走 服務(wù)器默認的界面展示,或者通過web.xml 配置error-code \ error-page來自定義界面處理異常;

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java語言簡介(動力節(jié)點Java學(xué)院整理)

    Java語言簡介(動力節(jié)點Java學(xué)院整理)

    Java是一門面向?qū)ο缶幊陶Z言,不僅吸收了C++語言的各種優(yōu)點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特征,下面通過本文給大家分享java語言的簡介,感興趣的朋友一起看看吧
    2017-03-03
  • Java多輸入框查詢需求實現(xiàn)方法詳解

    Java多輸入框查詢需求實現(xiàn)方法詳解

    這篇文章主要給大家介紹了Java多輸入框查詢需求實現(xiàn)的相關(guān)資料,文中通過代碼以及圖文介紹的非常詳細,對大家學(xué)習(xí)或者使用Java具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-10-10
  • Mybatis 動態(tài)sql的編寫與開啟二級緩存

    Mybatis 動態(tài)sql的編寫與開啟二級緩存

    二級緩存是Mapper級別的緩存,多個SqlSession去操作同一個Mapper中的SQL語句,則這些SqlSession可以共享二級緩存,即二級緩存是跨SqlSession的,這篇文章主要介紹了Mybatis 動態(tài)sql的編寫|開啟二級緩存,需要的朋友可以參考下
    2023-02-02
  • java 開發(fā)中網(wǎng)絡(luò)編程之IP、URL詳解及實例代碼

    java 開發(fā)中網(wǎng)絡(luò)編程之IP、URL詳解及實例代碼

    這篇文章主要介紹了java 開發(fā)中網(wǎng)絡(luò)編程之IP、URL詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 淺談Mybatis傳參類型如何確定

    淺談Mybatis傳參類型如何確定

    最近有小伙伴在討論#{}與${}的區(qū)別時,有提到#{}是用字符串進行替換,本文主要介紹了mapper接口中不同的參數(shù)類型,最終拼接sql中是如何進行替換的,感興趣的可以了解一下
    2021-10-10
  • 解決

    解決"XML Parser Error on line 1: 前言中不允許有內(nèi)容"錯誤

    解決用windows自帶的記事編輯xml文件后出現(xiàn) "XML Parser Error on line 1: 前言中不允許有內(nèi)容。"的錯誤
    2018-02-02
  • Java創(chuàng)建對象的四種方式詳解

    Java創(chuàng)建對象的四種方式詳解

    這篇文章主要介紹了Java創(chuàng)建對象的四種方式詳解,如果我們不想利用默認構(gòu)造器來創(chuàng)建java對象,而想利用指定的構(gòu)造器來創(chuàng)建java對象,則需要利用Construtor對象,每個Construtor對應(yīng)一個構(gòu)造器,需要的朋友可以參考下
    2023-11-11
  • Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    Java中Buffer緩沖區(qū)的ByteBuffer類詳解

    這篇文章主要介紹了Java中Buffer緩沖區(qū)的ByteBuffer類詳解,ByteBuffer類是Java NIO庫中的一個重要類,用于處理字節(jié)數(shù)據(jù),它提供了一種靈活的方式來讀取、寫入和操作字節(jié)數(shù)據(jù),ByteBuffer類是一個抽象類,可以通過靜態(tài)方法創(chuàng)建不同類型的ByteBuffer對象,需要的朋友可以參考下
    2023-10-10
  • springboot集成開發(fā)實現(xiàn)商場秒殺功能

    springboot集成開發(fā)實現(xiàn)商場秒殺功能

    這篇文章主要介紹了springboot集成實現(xiàn)商品秒殺功能,秒殺系統(tǒng)業(yè)務(wù)流程,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • Java多線程——基礎(chǔ)概念

    Java多線程——基礎(chǔ)概念

    這篇文章主要介紹了java多線程編程實例,分享了幾則多線程的實例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下,希望可以幫到你
    2021-07-07

最新評論