Java 如何向Wink客户端注册Jackson提供商?
我正在尝试建立一个玩具应用程序(有一天可能会变成一个真正的应用程序)。我遇到了Wink和Jackson的问题。我有两个应用程序:一个在jetty上运行wink服务器,似乎可以提供一些JSON数据;其中一个在jetty上运行wink客户端并接收JSON数据。问题在于自动将JSON数据反序列化回我的JavaBean中 以下是我在wink客户端操作中使用的代码:Java 如何向Wink客户端注册Jackson提供商?,java,json,jax-rs,jackson,apache-wink,Java,Json,Jax Rs,Jackson,Apache Wink,我正在尝试建立一个玩具应用程序(有一天可能会变成一个真正的应用程序)。我遇到了Wink和Jackson的问题。我有两个应用程序:一个在jetty上运行wink服务器,似乎可以提供一些JSON数据;其中一个在jetty上运行wink客户端并接收JSON数据。问题在于自动将JSON数据反序列化回我的JavaBean中 以下是我在wink客户端操作中使用的代码: RestClient client = new RestClient(); Resource resource = client.resou
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客户端上注册
是否可以使第一个代码段正常运行?如果是,怎么做
(顺便说一句,另一个问题可能是我的用户类缺少注释。现在没有注释。可能我需要一些…我希望我能帮助注册;但关于注释,我认为Jackson不需要任何注释来尝试反序列化值。如果您缺少所需的内容,您将得到不同类型的异常。步骤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;
}
}
步骤3:创建org.apache.wink.client.Resource
,使用get(Class responseEntity)
方法,现在一切都将按预期工作
Resource resource = client.resource("http://localhost:8081/helloworld");
User user = resource.accept(MediaType.APPLICATION_JSON).get(User.class);
如果您想真正熟练地使用它,可以使用Spring来设置
ClientConfig
bean,并将其注入到您的操作中。然后,您每次只需调用new RestClient(clientConfig)
,就不用担心复制整个设置了。我在尝试编写一些集成测试,为我的rest插件发布一个对象时遇到了这个问题
您可以向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);
}
如果您使用的是maven,您可以确保Jackson位于测试类路径上(检查兼容版本):
org.codehaus.jackson
jackson core asl
1.9.1
测试
org.codehaus.jackson
杰克逊·贾克斯
1.9.1
测试
org.codehaus.jackson
杰克逊地图绘制者
1.9.1
测试
org.codehaus.jackson
杰克逊xc
1.9.1
测试
这对我不起作用。我的类有jaxb注释,系统应用程序提供程序似乎会干扰jackson json提供程序。解决方案是在设置应用程序之前在ClientConfig上调用setLoadWinkApplications(false)。
@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());
}
<!-- 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>