本文介紹了Spring Reactive WebFlux–如何定制BadRequest錯(cuò)誤消息的處理方法,對(duì)大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
在我的請(qǐng)求處理程序中,如果傳入的accountId
不能轉(zhuǎn)換為有效的ObjectId
,我希望捕獲錯(cuò)誤并發(fā)回有意義的消息;然而,這樣做會(huì)導(dǎo)致返回類型不兼容,并且我不知道如何實(shí)現(xiàn)這個(gè)相當(dāng)簡(jiǎn)單的用例。
我的代碼:
@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)));
因?yàn)樗诹硪粋€(gè)return
語句中給出了不兼容的類型錯(cuò)誤:
error: incompatible types: Mono<ResponseEntity<Account>> cannot be converted to Mono<ResponseEntity<?>>
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
顯然,將方法的返回類型更改為Mono<?>
是可行的,但隨后的響應(yīng)是ResponseEntity
的序列化JSON,這不是我想要的。
我也嘗試過使用onErrorXxxx()
方法,但它們?cè)谶@里也不起作用,因?yàn)檗D(zhuǎn)換錯(cuò)誤甚至在計(jì)算通量之前就發(fā)生了,而且我只得到了一個(gè)帶有空消息的";vanilla";400錯(cuò)誤。
我唯一能想到的解決方法就是向Account
對(duì)象添加一個(gè)message
字段并返回該字段,但這確實(shí)是一個(gè)可怕的黑客攻擊。
推薦答案
@Thomas-andolf的回答幫助我找到了實(shí)際的解決方案。
對(duì)于將來遇到這個(gè)問題的任何人來說,我實(shí)際上是如何解決這個(gè)難題的(當(dāng)然,您仍然需要try/catch
來攔截ObjectId
構(gòu)造函數(shù)拋出的錯(cuò)誤):
@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()
在這里不起作用(我確實(shí)在它的所有變體中嘗試過),因?yàn)樗枰?code>Mono<ResponseEntity<Account>>,并且無法從錯(cuò)誤狀態(tài)生成一個(gè)(在添加消息正文時(shí))。
這篇關(guān)于Spring Reactive WebFlux–如何定制BadRequest錯(cuò)誤消息的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,