web-dev-qa-db-ja.com

RESTサービスの例外のhttpステータスコードを返す方法

私のアプリケーションには、残りのレイヤー、サービスレイヤー、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);

解決策を提案して助けてください

7
Sunil Rk

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...
}

アップデート2

また、同じ例外を異なる状態で再利用するのではなく、新しい例外を定義することをお勧めします。このように、BusinessExceptionから拡張する新しいValidationExceptionを定義できます。

public class ValidationException extends BusinessException{

    public ValidationException() {
        super(ErrorEnumeration.VALIDATION_FAILED);
    }
}

この方法を使用することで、すべてのBusinessExceptionを処理できますが、それらを識別したり、Jax-rs例外にマップしたりする方が簡単です。

9
bhdrkn