5

私はJerseyClientAPIを次のように使用しています:-

User user = webRsrc.accept(MediaType.APPLICATION_XML).post(User.class, usr);

したがって、JAXB注釈付きクラスであるUserクラスのオブジェクトでの応答を期待しています。ただし、エラーxmlが発生することもあり、そのためにJAXBクラスErrorResponseを作成しました。

問題は、リクエストがUserではなくErrorResponseのオブジェクトを返す場合、どうすればそれを処理できるかということです。

私はこのように試しました-

ClientResponse response=null;
try {

        response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);
        User usr = response.getEntity(User.class);    
    }catch(Exception exp)
    {
       ErrorResponse err = response.getEntity(ErrorResponse.class);    
    }

しかし、catchブロックでgetEntity()を使用しようとすると、次の例外がスローされます

[org.xml.sax.SAXParseException: Premature end of file.]
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:107)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:532)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:491) .....

getEntity()を1回呼び出した後、inputstreamが使い果たされたようです。

4

3 に答える 3

10

「RESTの考え方」全体でポイントを逃したと思います。
簡単な答え: はい、getEntity は 1 回しか呼び出すことができません。どのエンティティを取得する必要があるかを知るには、返された HTTP ステータスを確認する必要があります。

サーバー側:

  1. REST API を設計するときは、常にHTTP RFCに関する適切なステータス コードを使用する必要があります。
  2. その点については、ExceptionMapper インターフェースの使用を検討してください( 「NotFoundException」の例を次に示します)。

これで、サーバーは User オブジェクトで "HTTP status OK - 200" を返すか、エラー オブジェクトでエラー ステータスを返します。

クライアント側:

戻りステータスを確認し、API 仕様に従って動作を調整する必要があります。これは簡単で汚いコードサンプルです:

ClientResponse response=null;

response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);

int status = response.getStatus();

if (Response.Status.OK.getStatusCode() == status) {

  // normal case, you receive your User object
  User usr = response.getEntity(User.class);

} else {

  ErrorResponse err = response.getEntity(ErrorResponse.class);
}

注意: 返されるステータス コードによっては、このエラーが大きく異なる可能性があります (したがって、非常に異なる動作が必要になります)。

  • クライアント エラー 40X: クライアント リクエストが間違っています
  • サーバー エラー 500: サーバー側で予期しないエラーが発生しました
于 2010-03-04T18:49:49.157 に答える
2

この種のコードは、応答内のエラー メッセージまたはビジネス メッセージを管理するために使用できます。

protected <T> T call(String uri, Class<T> c) throws  BusinessException {


    WebResource res = new Client().create().resource(url);
    ClientResponse cresp = res.get(ClientResponse.class);
    InputStream respIS = cresp.getEntityInputStream();


    try {
        // Managing business or error response
        JAXBContext jCtx = JAXBContext.newInstance(c, BeanError.class);
        Object entity = jCtx.createUnmarshaller().unmarshal(respIS);

        // If the response is an error, throw an exception
        if(entity instanceof  BeanError) {
            BeanError error = (BeanError) entity;
            throw new  BusinessException(error);

        // If this not an error, this is the business response
        } else {
            return (T) entity;
        }

    } catch (JAXBException e) {

        throw(new BusinessException(e));
    }



}
于 2010-12-08T10:27:02.123 に答える