JacksonプロバイダーをWinkクライアントに登録するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4330363

質問

おもちゃのアプリケーションをセットアップしようとしています(いつか実際のアプリケーションに提出する可能性があります)。ウィンクとジャクソンの問題に遭遇しています。 2つのアプリケーションがあります。1つはJettyでWink-Serverを実行し、JSONデータを正常に提供しているようです。 JettyでWink-Clientを実行し、JSONデータを正常に受信します。この問題は、JSONデータを私のJava Beanに自動的にゆるくすることにあります。

これが私がWinkクライアントのアクションで使用しているコードです:

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

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

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 Serverでプロバイダーを登録する方法は、Winkクライアントではありません。

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

(余談ですが、他の問題は、ユーザークラスで注釈が欠けていることです。今は何もありません。多分私はいくつか必要です...)

役に立ちましたか?

解決

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

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:アクションで、aを作成します org.apache.wink.client.ClientConfig あなたのための org.apache.wink.client.RestClient. 。これにより、追加できます org.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);

あなたがそれについて本当に滑らかになりたいなら、あなたはスプリングを使用してセットアップすることができます ClientConfig あなたの行動に豆を入れて注入します。その後、電話するだけです new RestClient(clientConfig) 毎回、セットアップ全体を複製することを心配しないでください。

他のヒント

RESTプラグインのオブジェクトを投稿する統合テストを作成しようとしたときに、この問題に遭遇しました。

新しいクラスをスピンアウトするのではなく、ジャクソンプロバイダーにインラインクラスを提供できます。

  @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 ClassPathに参加していることを確認できます(互換性のあるバージョンを確認してください):

<!-- 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>

登録を手伝ってくれたらいいのにと思います。しかし、注釈に関しては、ジャクソンが価値を復活させようとするために必要なことはないと思います。必要なものが足りない場合は、異なる種類の例外が得られます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top