4

おもちゃのアプリケーションをセットアップしようとしています(いつか実際のアプリケーションになる可能性があります)。ウィンクとジャクソンで問題が発生しています。2つのアプリケーションがあります。1つはjettyでwink-serverを実行し、JSONデータを正常に提供しているようです。1つはjettyでwink-clientを実行し、JSONデータを正常に受信します。問題は、JSONデータを自動的に逆シリアル化してJavaBeanに戻すことにあります。

ウィンククライアントアクションで使用するコードは次のとおりです。

RestClient client = new RestClient();
Resource resource = client.resource("http://localhost:8081/helloworld");
User user = resource.accept(MediaType.APPLICATION_JSON).get(User.class);

Strutsアクションを実行しようとしたときに受け取るエラーは次のとおりです。

java.lang.RuntimeException: No javax.ws.rs.ext.MessageBodyReader found for type class my.package.structure.User and media type application/json. Verify that all entity providers are correctly registered.
org.apache.wink.client.internal.handlers.ClientResponseImpl.readEntity(ClientResponseImpl.java:123)
org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:65)
org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:52)
org.apache.wink.client.internal.ResourceImpl.invoke(ResourceImpl.java:186)
org.apache.wink.client.internal.ResourceImpl.get(ResourceImpl.java:294)
my.package.structure.action.HelloWorldAction.execute(HelloWorldAction.java:29)
...

最初のコードスニペットの最後の行を次の行に置き換えると、すべてが正常に機能し、ダンディになります。

String message = resource.accept(MediaType.APPLICATION_JSON).get(String.class);
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(message, User.class);

データが正常に処理されていることは明らかですが、問題は、JacksonJsonProviderクラスがWinkクライアントに登録されていないという事実にあるようです。プロバイダーをWinkサーバーに登録する方法はたくさんありますが、Winkクライアントは登録していません。

最初のコードスニペットを正しく動作させることは可能ですか?もしそうなら、どのように?

(余談ですが、もう1つの問題は、Userクラスに注釈がないことです。現在は注釈がありません。必要な場合があります...)

4

3 に答える 3

7

javax.ws.rs.core.Applicationステップ 1:シングルトンを設定できるように拡張するクラスを作成します。

import java.util.Collections;
import java.util.Set;
import javax.ws.rs.core.Application;

public class ClientApplication extends Application {

    private Set<Object> singletons = Collections.emptySet();

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }

    public void setSingletons(final Set<Object> singletons) {
        this.singletons = singletons;
    }
}

ステップ 2: アクションで、 の を作成org.apache.wink.client.ClientConfigしますorg.apache.wink.client.RestClientorg.codehaus.jackson.jaxrs.JacksonJsonProviderこれにより、プロバイダー リストにを追加できます。

ClientApplication clientApplication = new ClientApplication();
Set<Object> s = new HashSet<Object>();
s.add(new JacksonJsonProvider());
clientApplication.setSingletons(s);
ClientConfig clientConfig = new ClientConfig().applications(clientApplication);
RestClient restClient = new RestClient(clientConfig);

ステップ 3: を作成し、メソッドをorg.apache.wink.client.Resource使用するget(Class<T> responseEntity)と、すべてが期待どおりに機能するようになります。

Resource resource = client.resource("http://localhost:8081/helloworld");
User user = resource.accept(MediaType.APPLICATION_JSON).get(User.class);

うまく使いこなしたい場合は、Spring を使用してClientConfigBean をセットアップし、それをアクションに注入できます。new RestClient(clientConfig)そうすれば、毎回呼び出すことができ、セットアップ全体を複製することを心配する必要はありません。

于 2010-12-07T17:02:22.320 に答える
3

残りのプラグインのオブジェクトを POST するいくつかの統合テストを作成しようとしたときに、この問題に遭遇しました。

新しいクラスをスピンアウトする代わりに、Jackson プロバイダーにインライン クラスを提供できます。

  @Before
public void setup(){

    javax.ws.rs.core.Application app = new javax.ws.rs.core.Application() {
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(JacksonJaxbJsonProvider.class);
            return classes;
        }

    };
    //create auth handler
    clientConfig = new ClientConfig();
    clientConfig.applications(app);
    BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
    basicAuthSecurityHandler.setUserName(USERNAME);
    basicAuthSecurityHandler.setPassword(PASSWORD); 
    clientConfig.handlers(basicAuthSecurityHandler);
    //create client usin auth and provider
    client = new RestClient(clientConfig);

}

その後、注釈付きオブジェクトを投稿して使用できます。

@Test
public void aReadWriteTokenCanBeCreatedAsRequested(){ 
    ClientResponse response = client.resource(resourceUrlToken).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(readAndWriteToken);
    assertEquals("Could not create token needed for test",200,response.getStatusCode());
    readAndWriteToken = response.getEntity(TokenResource.class);
    assertNotNull("Returned token does not have UUID",readAndWriteToken.getUuid());

}

Maven を使用している場合は、Jackson がテスト クラスパス上にあることを確認できます (互換性のあるバージョンを確認してください)。

<!-- TEST DEPENDENCIES -->
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
于 2014-08-01T15:16:34.680 に答える
0

登録を手伝いたいのですが。しかし、アノテーションに関しては、Jacksonが値を逆シリアル化しようとするために必要なものはないと思います。必要なものが不足している場合は、別の種類の例外が発生します。

于 2010-12-03T17:15:58.990 に答える