本文介紹了Spring Reactive WebFlux–如何定制BadRequest錯誤消息的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
在我的請求處理程序中,如果傳入的accountId
不能轉換為有效的ObjectId
,我希望捕獲錯誤并發回有意義的消息;然而,這樣做會導致返回類型不兼容,并且我不知道如何實現這個相當簡單的用例。
我的代碼:
@GetMapping("/{accountId}")
public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
log.debug(GETTING_DATA_FOR_ACCOUNT, accountId);
try {
ObjectId id = new ObjectId(accountId);
return repository.findById(id)
.map(ResponseEntity::ok)
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
} catch (IllegalArgumentException ex) {
log.error(MALFORMED_OBJECT_ID, accountId);
// TODO(marco): find a way to return the custom error message. This seems to be currently
// impossible with the Reactive API, as using body(message) changes the return type to
// be incompatible (and Mono<ResponseEntity<?>> does not seem to cut it).
return Mono.just(ResponseEntity.badRequest().build());
}
}
body(T body)
方法更改返回的Mono
的類型,使其為String
)Mono<ResponseEntity<String>>
;但是,將該方法的返回類型更改為Mono<ResponseEntity<?>>
也不起作用:
...
return Mono.just(ResponseEntity.badRequest().body(
MALFORMED_OBJECT_ID.replace("{}", accountId)));
因為它在另一個return
語句中給出了不兼容的類型錯誤:
error: incompatible types: Mono<ResponseEntity<Account>> cannot be converted to Mono<ResponseEntity<?>>
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
顯然,將方法的返回類型更改為Mono<?>
是可行的,但隨后的響應是ResponseEntity
的序列化JSON,這不是我想要的。
我也嘗試過使用onErrorXxxx()
方法,但它們在這里也不起作用,因為轉換錯誤甚至在計算通量之前就發生了,而且我只得到了一個帶有空消息的";vanilla";400錯誤。
我唯一能想到的解決方法就是向Account
對象添加一個message
字段并返回該字段,但這確實是一個可怕的黑客攻擊。
推薦答案
@Thomas-andolf的回答幫助我找到了實際的解決方案。
對于將來遇到這個問題的任何人來說,我實際上是如何解決這個難題的(當然,您仍然需要try/catch
來攔截ObjectId
構造函數拋出的錯誤):
@GetMapping("/{accountId}")
public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
return Mono.just(accountId)
.map(acctId -> {
try {
return new ObjectId(accountId);
} catch (IllegalArgumentException ex) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
MALFORMED_OBJECT_ID));
}
})
.flatMap(repository::findById)
.map(ResponseEntity::ok)
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
}
要真正看到返回的Body中的message
,需要在application.properties
中添加server.error.include-message=always
(參見here)。
使用onError()
在這里不起作用(我確實在它的所有變體中嘗試過),因為它需要Mono<ResponseEntity<Account>>
,并且無法從錯誤狀態生成一個(在添加消息正文時)。
這篇關于Spring Reactive WebFlux–如何定制BadRequest錯誤消息的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,