有沒有辦法在沒有任何編譯器警告和@SuppressUnchecked
註釋的情況下乾淨地編寫此代碼?
我不想在這種情況下襬脫編譯器警告。可能的乾淨解決方案之一(至少沒有編譯器警告)拒絕Optional.map
贊成簡單的if
/else
或?:
驅動戰略不適用於流暢接口的想法。
static <T, U> ResponseEntity<?> okOrNotFound(final Optional<T> optional, final Supplier<? extends U> orElse) {
return okOrNotFound(optional, "Not found", orElse);
}
static <T, U> ResponseEntity<?> okOrNotFound(final Optional<T> optional, final String message, final Supplier<? extends U> orElse) {
return optional.isPresent()
? status(OK).body(optional.get())
: status(NOT_FOUND).body(new NotFound<>(orElse.get(), message));
}
@RequestMapping(method = GET, value = "/")
ResponseEntity<?> get(
@RequestParam("user") final String user,
@RequestParam("uuid") final UUID uuid
) {
final Optional<Dashboard> dashboard = dashboardService.getDashboard(user, uuid);
return okOrNotFound(dashboard,() -> uuid);
}
注意orElse
是不是真的你想要什麼:orElseGet
是懶惰,如果給定可選的值不存在只調用它的供應商。
然而,Spring提供了一種更好的方式來實現你所需要的,我相信這是一種更乾淨的方式。看看專爲此目的而設計的controller advices。
// I would prefer a checked exception having a super class like ContractException
// However you can superclass this one into your custom super exception to serve various purposes and contain exception-related data to be de-structured below
final class NotFoundException
extends NoSuchElementException {
private final Object entity;
private NotFoundException(final Object entity) {
this.entity = entity;
}
static NotFoundException notFoundException(final Object entity) {
return new NotFoundException(entity);
}
Object getEntity() {
return entity;
}
}
現在REST控制器方法變爲:
@RequestMapping(method = GET, value = "/")
Dashboard get(
@RequestParam("user") final String user,
@RequestParam("uuid") final UUID uuid
) {
return dashboardService.getDashboard(user, uuid)
.orElseThrow(() -> notFoundException(uuid));
}
春天是足夠聰明的對象轉換爲status(OK).body(T)
本身,所以我們只是拋包含單個對象,我們感興趣的是一個例外下一步。 ,樣品控制器例外的建議可能如下:
@ControllerAdvice
final class ExceptionControllerAdvice {
@ExceptionHandler(NotFoundException.class)
ResponseEntity<NotFound<?>> acceptNotFoundException(final NotFoundException ex) {
return status(NOT_FOUND).body(notFound(ex));
}
}
其中notFound()
方法是這樣實現的:
static NotFound<?> notFound(final NotFoundException ex) {
return notFound(ex, "Not found");
}
static NotFound<?> notFound(final NotFoundException ex, final String message) {
return new NotFound<>(ex.getEntity(), message);
}
對於我秒殺項目提供了以下結果:
- _http://本地主機:8080 /??用戶=所有者& UUID = 00000000-0000-0000-0000-000000000000 -
{"description":"dashboard owned by owner"}
- _http://本地主機:8080 /用戶=用戶& UUID = 00000000-0000-0000-0000-000000000000 -
{"entity":"00000000-0000-0000-0000-000000000000","message":"Not found"}
將** >'添加到**兩種方法**的簽名中的'ResponseEntity',導致警告消失。 – slim
「有沒有辦法在沒有任何編譯器警告的情況下乾淨地編寫代碼」是的,用if/else。 Intellij是錯誤的。 (我intellij不建議「簡化」)。 –
@AndyTurner不同意。 'if(x.isPresent(){return f(x.get());} else {return y;}'是一個反模式。'return x.map(F:f)。orElse(y)'是Right事情要做 – slim