私のアプリケーションには、残りのレイヤー、サービスレイヤー、DBレイヤーなどのさまざまなレイヤーがあり、ビジネスシナリオに応じて、サービスレイヤーからさまざまなビジネス例外を処理しています。
しかし今、私は400、403、409、412 ..のような異なるHTTPコードをREST応答に設定する必要があります。
さまざまなシナリオに基づいてさまざまなHTTPステータスコードを設定するにはどうすればよいですか?
アスペクト、例外マッパー、または....のような最も実行可能な方法はどれですか?
RESTレイヤーでHTTPステータスを設定できるのは1回だけなので( これを参照 )、例外がサービスレイヤーからのものであるため、別のHTTPコードにマップできません。
私の例外クラスは次のようになります。
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
public BusinessException(ErrorEnumeration error) {
}
public BusinessException(Exception e, ErrorEnumeration error) {
}
}
例外は次のようにサービスからスローされます。
throw new BusinessException(ErrorEnumeration.VALIDATION_FAILED);
解決策を提案して助けてください
Jax-rsで定義された例外を使用することも、独自の例外を使用することもできます。 Fistはビジネスの例外をキャッチし、それらをjax-rsバージョンに変換します。たとえば、404の場合、javax.ws.rs.NotFoundException.
をスローできます
javax.ws.rs.ClientErrorException
から拡張して、独自の例外を作成することもできます。
これは409の例です-競合ステータスの例外
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;
public class ConflictException extends ClientErrorException{
public ConflictException(Response.Status status) {
super(Response.Status.CONFLICT); // 409
}
}
最も単純で実行可能な方法は、ビジネス例外をキャッチし、jax-rs例外を使用してそれらを再スローすることです。
try{
businessService.executeBusinessRule();
}catch (BusinessException e){
// It is better if your BusinessException has some child class to handle
if(e.getError() == ErrorEnumeration.VALIDATION_FAILED){
throw new BadRequestException();
}else{
throw new ConflictException();
}
}
Springを使用している場合は、aopを使用してこれらの例外をいつでもキャッチできます。
@Aspect
public class BusinessExceptionInterceptor{
@AfterThrowing(pointcut = "execution(* com.your.service.packge..* (..))", throwing = "e")
public void errorInterceptor(BusinessException e) {
// re-throw again...
}
また、同じ例外を異なる状態で再利用するのではなく、新しい例外を定義することをお勧めします。このように、BusinessExceptionから拡張する新しいValidationExceptionを定義できます。
public class ValidationException extends BusinessException{
public ValidationException() {
super(ErrorEnumeration.VALIDATION_FAILED);
}
}
この方法を使用することで、すべてのBusinessExceptionを処理できますが、それらを識別したり、Jax-rs例外にマップしたりする方が簡単です。