0

Javaアプリケーションを開発しています。私のリソースクラスには、すべてのJAX-RS APIメソッドが定義されています。私はその障害シナリオのための特定の例外を作成し、それを投げています各サービスクラスの障害シナリオのそれぞれについて例外を使用したJava REST APIのアプリケーションおよびビジネスの失敗シナリオの処理

class Resource { 

    // Services are injected. 
    // Each service has a couple of failure scenarios. 
    // Exp. Request Not valid, Id not valid, Database internal error, etc. 
    DBService dbService; 
    validationService validationService; 
    searchService searchService; 

    @GET(user/:id) 
    public User getUser(int id) { 
     try { 
      validationService.validate(request); 
      dbService.getUser(id); 
      searchService.index(request); 
      ... 
     } catch (UserNotFoundException e) { 
      // return proper http response code and message 
     } catch (UserBannedException e) { 
      ... 
     } catch (DBInternalError e) { 
      ... 
     } ... 

    } 
} 

:また、私は、独自のサービスクラスに各タスクを委任するために、私のリソースクラスに依存性注入を使用していますAPIクラスでこれらの例外をすべて処理するサービスクラスです。私は例外シナリオについて自分のリソースへのシグナルとしてExceptionを使用し、適切なHTTPステータスコードとメッセージを返します。

私は多くのExceptionクラスを作成していますが、Resourceクラスにはさまざまな失敗シナリオのcatchブロックの長いリストが含まれています。

たとえば、私のvalidationServiceでは、例外の代わりにfalse booleanを返し、私のリソースにはif/else文を入れ、適切なステータスコードを返します。しかし、私はこのソリューションが好きではない。なぜなら、それはif/elseステートメントとそれほど線形でないAPIで私のAPIをいっぱいにするからです。

私のユースケースには多くの例外クラスを用意しても問題ありません。また、私の使用に適したアーキテクチャはありますか?

+0

これらの例外を処理する意味のある方法がある場合は、別の方法でそれを行ってください。そうでない場合は、例外のサブクラス化、または意味のない例外への統合を検討してください。 – CollinD

+0

例外をスローするのではなく、エラーコールバックオブジェクトを含めるようにサービスクラスAPIを再設計することができます。その後、適切なエラー処理オブジェクトを渡して、 'throw/catch'を完全になくします。 –

+0

[JAX-RS/Jerseyのエラー処理をカスタマイズする方法は?](http://stackoverflow.com/questions/583973/jax-rs-jersey-how-to-customize-error-handling) – jaco0646

答えて

0

あなたのリソースのレイヤーにそれらをキャッチしないことをお勧めします。

サービスレイヤーはビジネスロジックを認識している必要があります。そのため、チェックと検証を行い、適切なエラーメッセージでビジネス例外をスローし、例外マッパー-にキャッチして相関応答を作成させます。

else文場合はのtry catchブロックの多くを持っていないこの方法です。

例:

PersonResource.java

@RequestScoped 
@Path("/person") 
@Produces({ "application/json" }) 
@Consumes({ "application/json" }) 
public class PersonResource { 

    public PersonResource() {} 

    @Inject 
    PersonService personService; 

    @POST 
    @Path("/add") 
    public void addPerson(Person person) throws MyValidationException{ 
     personService.add(person); 
    } 
... 

PersonService.java

@RequestScoped 
public class PersonServiceImpl implements PersonService { 

    @Inject 
    PersonDAO personDAO; 

    @Transactional 
    @Override 
    public Long add(Person person) throws MyValidationException { 

    //checking for existing person 
    List<Person> list = personDAO.find(person.getName(), person.getDob()); 

    //if not found, save new person 
    if(list == null || list.isEmpty()){ 
     Long id = personDAO.save(person); 
     return id; 
    } 

    //otherwise throw exception 
    String message = "Person already exists: '" + person.getName + "'"; 
    throw new MyValidationException(message); 
} 
... 

ValidationExceptionMapper.java

こうすることで、ビジネス例外が作成されているのと同じ数の例外マッパーを作成できるため、ビジネスやリソースのレイヤーがすべての例外処理で汚染されることはありません。

例外マッパーは例外の処理方法も知っています。

クライアントに応答エラーのステータスと本文(エラーメッセージ)を処理させます。

関連する問題