国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解Spring Boot2 Webflux的全局異常處理

詳解Spring Boot2 Webflux的全局異常處理

2021-06-23 13:50Aoho''s Blog Java教程

這篇文章主要介紹了詳解Spring Boot2 Webflux的全局異常處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文首先將會回顧spring 5之前的springmvc異常處理機(jī)制,然后主要講解spring boot 2 webflux的全局異常處理機(jī)制。

springmvc的異常處理

spring 統(tǒng)一異常處理有 3 種方式,分別為:

  • 使用 @exceptionhandler 注解
  • 實(shí)現(xiàn) handlerexceptionresolver 接口
  • 使用 @controlleradvice 注解

使用 @exceptionhandler 注解

用于局部方法捕獲,與拋出異常的方法處于同一個controller類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@controller
public class buzcontroller {
 
  @exceptionhandler({nullpointerexception.class})
  public string exception(nullpointerexception e) {
    system.out.println(e.getmessage());
    e.printstacktrace();
    return "null pointer exception";
  }
 
  @requestmapping("test")
  public void test() {
    throw new nullpointerexception("出錯了!");
  }
}

如上的代碼實(shí)現(xiàn),針對 buzcontroller 拋出的 nullpointerexception 異常,將會捕獲局部異常,返回指定的內(nèi)容。

實(shí)現(xiàn) handlerexceptionresolver 接口

通過實(shí)現(xiàn) handlerexceptionresolver 接口,定義全局異常:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@component
public class custommvcexceptionhandler implements handlerexceptionresolver {
 
  private objectmapper objectmapper;
 
  public custommvcexceptionhandler() {
    objectmapper = new objectmapper();
  }
 
  @override
  public modelandview resolveexception(httpservletrequest request, httpservletresponse response,
                     object o, exception ex) {
    response.setstatus(200);
    response.setcontenttype(mediatype.application_json_value);
    response.setcharacterencoding("utf-8");
    response.setheader("cache-control", "no-cache, must-revalidate");
    map<string, object> map = new hashmap<>();
    if (ex instanceof nullpointerexception) {
      map.put("code", responsecode.np_exception);
    } else if (ex instanceof indexoutofboundsexception) {
      map.put("code", responsecode.index_out_of_bounds_exception);
    } else {
      map.put("code", responsecode.catch_exception);
    }
    try {
      map.put("data", ex.getmessage());
      response.getwriter().write(objectmapper.writevalueasstring(map));
    } catch (exception e) {
      e.printstacktrace();
    }
    return new modelandview();
  }
}

如上為示例的使用方式,我們可以根據(jù)各種異常定制錯誤的響應(yīng)。

使用 @controlleradvice 注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@controlleradvice
public class exceptioncontroller {
  @exceptionhandler(runtimeexception.class)
  public modelandview handlerruntimeexception(runtimeexception ex) {
    if (ex instanceof maxuploadsizeexceededexception) {
      return new modelandview("error").addobject("msg", "文件太大!");
    }
    return new modelandview("error").addobject("msg", "未知錯誤:" + ex);
  }
 
  @exceptionhandler(exception.class)
  public modelandview handlermaxuploadsizeexceededexception(exception ex) {
    if (ex != null) {
      return new modelandview("error").addobject("msg", ex);
    }
 
    return new modelandview("error").addobject("msg", "未知錯誤:" + ex);
 
  }
}

和第一種方式的區(qū)別在于, exceptionhandler 的定義和異常捕獲可以擴(kuò)展到全局。

spring 5 webflux的異常處理

webflux支持mvc的注解,是一個非常便利的功能,相比較于routefunction,自動掃描注冊比較省事。異常處理可以沿用exceptionhandler。如下的全局異常處理對于restcontroller依然生效。

?
1
2
3
4
5
6
7
8
9
10
11
@restcontrolleradvice
public class customexceptionhandler {
  private final log logger = logfactory.getlog(getclass());
 
  @exceptionhandler(exception.class)
  @responsestatus(code = httpstatus.ok)
  public errorcode handlecustomexception(exception e) {
    logger.error(e.getmessage());
    return new errorcode("e","error" );
  }
}

webflux示例

webflux提供了一套函數(shù)式接口,可以用來實(shí)現(xiàn)類似mvc的效果。我們先接觸兩個常用的。

controller定義對request的處理邏輯的方式,主要有方面:

  • 方法定義處理邏輯;
  • 然后用@requestmapping注解定義好這個方法對什么樣url進(jìn)行響應(yīng)。

在webflux的函數(shù)式開發(fā)模式中,我們用handlerfunction和routerfunction來實(shí)現(xiàn)上邊這兩點(diǎn)。

handlerfunction

handlerfunction 相當(dāng)于controller中的具體處理方法,輸入為請求,輸出為裝在mono中的響應(yīng):

?
1
mono<t> handle(serverrequest var1);

在webflux中,請求和響應(yīng)不再是webmvc中的servletrequest和servletresponse,而是serverrequest和serverresponse。后者是在響應(yīng)式編程中使用的接口,它們提供了對非阻塞和回壓特性的支持,以及http消息體與響應(yīng)式類型mono和flux的轉(zhuǎn)換方法。

?
1
2
3
4
5
6
7
@component
public class timehandler {
  public mono<serverresponse> gettime(serverrequest serverrequest) {
    string timetype = serverrequest.queryparam("type").get();
    //return ...
  }
}

如上定義了一個 timehandler ,根據(jù)請求的參數(shù)返回當(dāng)前時間。

routerfunction

routerfunction ,顧名思義,路由,相當(dāng)于 @requestmapping ,用來判斷什么樣的url映射到那個具體的 handlerfunction 。輸入為請求,輸出為mono中的 handlerfunction :

?
1
mono<handlerfunction<t>> route(serverrequest var1);

針對我們要對外提供的功能,我們定義一個route。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@configuration
public class routerconfig {
  private final timehandler timehandler;
 
  @autowired
  public routerconfig(timehandler timehandler) {
    this.timehandler = timehandler;
  }
 
  @bean
  public routerfunction<serverresponse> timerrouter() {
    return route(get("/time"), req -> timehandler.gettime(req));
  }
}

可以看到訪問/time的get請求,將會由 timehandler::gettime 處理。

功能級別處理異常

如果我們在沒有指定時間類型(type)的情況下調(diào)用相同的請求地址,例如/time,它將拋出異常。

mono和flux apis內(nèi)置了兩個關(guān)鍵操作符,用于處理功能級別上的錯誤。

使用onerrorresume處理錯誤

還可以使用onerrorresume處理錯誤,fallback方法定義如下:

?
1
mono<t> onerrorresume(function<? super throwable, ? extends mono<? extends t>> fallback);

當(dāng)出現(xiàn)錯誤時,我們使用fallback方法執(zhí)行替代路徑:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@component
public class timehandler {
  public mono<serverresponse> gettime(serverrequest serverrequest) {
    string timetype = serverrequest.queryparam("time").orelse("now");
    return gettimebytype(timetype).flatmap(s -> serverresponse.ok()
        .contenttype(mediatype.text_plain).syncbody(s))
        .onerrorresume(e -> mono.just("error: " + e.getmessage()).flatmap(s -> serverresponse.ok().contenttype(mediatype.text_plain).syncbody(s)));
  }
 
  private mono<string> gettimebytype(string timetype) {
    string type = optional.ofnullable(timetype).orelse(
        "now"
    );
    switch (type) {
      case "now":
        return mono.just("now is " + new simpledateformat("hh:mm:ss").format(new date()));
      case "today":
        return mono.just("today is " + new simpledateformat("yyyy-mm-dd").format(new date()));
      default:
        return mono.empty();
    }
  }
}

在如上的實(shí)現(xiàn)中,每當(dāng) gettimebytype() 拋出異常時,將會執(zhí)行我們定義的 fallback 方法。除此之外,我們還可以捕獲、包裝和重新拋出異常,例如作為自定義業(yè)務(wù)異常:

?
1
2
3
4
5
6
7
public mono<serverresponse> gettime(serverrequest serverrequest) {
  string timetype = serverrequest.queryparam("time").orelse("now");
  return serverresponse.ok()
      .body(gettimebytype(timetype)
          .onerrorresume(e -> mono.error(new serverexception(new errorcode(httpstatus.bad_request.value(),
              "timetype is required", e.getmessage())))), string.class);
}

使用onerrorreturn處理錯誤

每當(dāng)發(fā)生錯誤時,我們可以使用 onerrorreturn() 返回靜態(tài)默認(rèn)值:

?
1
2
3
4
5
6
7
public mono<serverresponse> getdate(serverrequest serverrequest) {
  string timetype = serverrequest.queryparam("time").get();
  return gettimebytype(timetype)
      .onerrorreturn("today is " + new simpledateformat("yyyy-mm-dd").format(new date()))
      .flatmap(s -> serverresponse.ok()
          .contenttype(mediatype.text_plain).syncbody(s));
}

全局異常處理

如上的配置是在方法的級別處理異常,如同對注解的controller全局異常處理一樣,webflux的函數(shù)式開發(fā)模式也可以進(jìn)行全局異常處理。要做到這一點(diǎn),我們只需要自定義全局錯誤響應(yīng)屬性,并且實(shí)現(xiàn)全局錯誤處理邏輯。

我們的處理程序拋出的異常將自動轉(zhuǎn)換為http狀態(tài)和json錯誤正文。要自定義這些,我們可以簡單地?cái)U(kuò)展 defaulterrorattributes 類并覆蓋其 geterrorattributes() 方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@component
public class globalerrorattributes extends defaulterrorattributes {
 
  public globalerrorattributes() {
    super(false);
  }
 
  @override
  public map<string, object> geterrorattributes(serverrequest request, boolean includestacktrace) {
    return assembleerror(request);
  }
 
  private map<string, object> assembleerror(serverrequest request) {
    map<string, object> errorattributes = new linkedhashmap<>();
    throwable error = geterror(request);
    if (error instanceof serverexception) {
      errorattributes.put("code", ((serverexception) error).getcode().getcode());
      errorattributes.put("data", error.getmessage());
    } else {
      errorattributes.put("code", httpstatus.internal_server_error);
      errorattributes.put("data", "internal server error");
    }
    return errorattributes;
  }
  //...有省略
}

如上的實(shí)現(xiàn)中,我們對 serverexception 進(jìn)行了特別處理,根據(jù)傳入的 errorcode 對象構(gòu)造對應(yīng)的響應(yīng)。

接下來,讓我們實(shí)現(xiàn)全局錯誤處理程序。為此,spring提供了一個方便的 abstracterrorwebexceptionhandler 類,供我們在處理全局錯誤時進(jìn)行擴(kuò)展和實(shí)現(xiàn):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@component
@order(-2)
public class globalerrorwebexceptionhandler extends abstracterrorwebexceptionhandler {
 
 //構(gòu)造函數(shù)
  @override
  protected routerfunction<serverresponse> getroutingfunction(final errorattributes errorattributes) {
    return routerfunctions.route(requestpredicates.all(), this::rendererrorresponse);
  }
 
  private mono<serverresponse> rendererrorresponse(final serverrequest request) {
 
    final map<string, object> errorpropertiesmap = geterrorattributes(request, true);
 
    return serverresponse.status(httpstatus.ok)
        .contenttype(mediatype.application_json_utf8)
        .body(bodyinserters.fromobject(errorpropertiesmap));
  }
}

這里將全局錯誤處理程序的順序設(shè)置為-2。這是為了讓它比 @order(-1) 注冊的 defaulterrorwebexceptionhandler 處理程序更高的優(yōu)先級。

該errorattributes對象將是我們在網(wǎng)絡(luò)異常處理程序的構(gòu)造函數(shù)傳遞一個的精確副本。理想情況下,這應(yīng)該是我們自定義的error attributes類。然后,我們清楚地表明我們想要將所有錯誤處理請求路由到rendererrorresponse()方法。最后,我們獲取錯誤屬性并將它們插入服務(wù)器響應(yīng)主體中。

然后,它會生成一個json響應(yīng),其中包含錯誤,http狀態(tài)和計(jì)算機(jī)客戶端異常消息的詳細(xì)信息。對于瀏覽器客戶端,它有一個whitelabel錯誤處理程序,它以html格式呈現(xiàn)相同的數(shù)據(jù)。當(dāng)然,這可以是定制的。

小結(jié)

本文首先講了spring 5之前的springmvc異常處理機(jī)制,springmvc統(tǒng)一異常處理有 3 種方式:使用 @exceptionhandler 注解、實(shí)現(xiàn) handlerexceptionresolver 接口、使用 @controlleradvice 注解;然后通過webflux的函數(shù)式接口構(gòu)建web應(yīng)用,講解spring boot 2 webflux的函數(shù)級別和全局異常處理機(jī)制(對于spring webmvc風(fēng)格,基于注解的方式編寫響應(yīng)式的web服務(wù),仍然可以通過springmvc統(tǒng)一異常處理實(shí)現(xiàn))。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://blueskykong.com/2018/12/18/webflux-error/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人三区 | 六月成人网| 午夜精品视频在线观看 | 伊人春色网 | 91精品综合久久久久久五月天 | 亚洲精品一区二区在线 | 91视频网页 | 精品在线一区二区 | 色婷婷一区二区三区 | 亚洲国产高清在线 | 久热精品在线视频 | 可以免费看黄的网站 | 午夜精品久久久久久久久久久久久 | 国产欧美精品区一区二区三区 | 亚洲国产精品人人爽夜夜爽 | www伊人 | 噜噜噜在线观看免费视频日本 | 中文字幕日韩有码 | 日韩精品免费视频 | av网站一区 | 国产成人av网站 | 亚洲精品久久久久久动漫 | 国产精品久久久久久久午夜 | 精品国产一区二区在线 | yy6080久久伦理一区二区 | 亚洲 激情 在线 | av在线免费观看网站 | 久草视频免费看 | 亚洲免费视频在线 | 成人综合视频在线 | 亚洲成人精品av | 免费观看www免费观看 | 99久久婷婷国产综合精品草原 | 日韩欧美在线播放 | 日韩一区二区三区视频 | 依人免费视频 | 国产亚洲精品美女久久久久久久久久 | 成人精品鲁一区一区二区 | 精品国产乱码一区二区三区 | 亚洲精品一区二区 | 日韩久久久 |