我正在尝试使用Jersey / JAX-RS实现RESTful Web服务客户端:
public class MyClient implements Closeable {
private Client client;
private FizzResource fizzResource;
// Several other resources omitted for brevity.
// Ctor, getters and setters, etc.
@Override
public void close() throws Exception {
client.destroy();
client.getExecutorService().shutdown();
}
}
public class FizzResource {
private Client client;
public Fizz saveFizz(Fizz fizz) {
WebResource webResource = client.resource("whatever");
ClientResponse response = webResource.accept(???).post(???);
if(response.getStatus() != 200) {
// do something...
} else {
// do something else...
}
}
}
我的问题是我不想使用JSON;相反,我想直接与我的实体合作(例如Fizz
)。我想使用Jackson自动执行JSON和我的实体之间的序列化(没有我必须在每个方法中明确地进行转换),但我没有看到这是可行的/可行的。理想情况下,我的saveFizz
方法可能如下所示:
public Fizz saveFizz(Fizz fizz) {
WebResource webResource = client.resource("whatever");
ClientResponse response = webResource.accept("application/json").post(fizz);
if(response.getStatus() != 200) {
throw new RuntimeException("Errors are bad, mkay?");
}
Fizz fizz = response.extractSomehow();
return fizz;
}
假设我的Fizz
课程已使用正确的杰克逊注释(JsonProperty
等)进行注释。
有什么想法吗?
答案 0 :(得分:2)
您可以使用Jackson的ObjectMapper:
final ObjectMapper mapper = new ObjectMapper();
mapper.readValue(response.getEntity(String.class), Fizz.class);
只要Fizz被正确注释,这应该可以满足您的需求。
还有其他选项,通常涉及实现自定义提供程序。
答案 1 :(得分:2)
您正在使用Jersey 1.x,所以请查看the user guide for JSON/POJO support
第一件事:我们需要确保您拥有jersey-json
模块
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey-version}</version>
</dependency>
此模块将包含所需的MessageBodyReader
和MessageBodyWriter
,可以在JSON中读取和写入POJO
第二件事:我们需要确保启用POJO映射支持功能。服务器/应用程序和客户端
带有web.xml的服务器
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
服务器程序化
public class MyApplication extends PackagesResourceConfig {
public MyApplication() {
getFeatures()..put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
}
}
请参阅其他Deployment Options
客户端配置
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
Client client = Client.create(clientConfig);
第三件事:我们只需要确保我们的资源方法正确注释,并且我们正确地调用客户端(以允许发现正确的编写器/读取器)。
对于接受JSON的方法,它应该使用@Consumed("application/json")
进行注释,如果该方法也在JSON中生成响应,则还应使用@Produces("application/json")
进行注释。所以它取决于你的方法的语义,包括哪些注释,它可以是一个或两个。
对于客户端,只要我们必须纠正配置,解压缩Java对象,只需要调用具有Java类型的getXxx
即可。
public void testGetFizz() {
// Directly extact
Fizz fizz = r.path("fizz").accept("application/json").get(Fizz.class);
System.out.println(fizz);
// Extract from ClientResponse
ClientResponse response = r.path("fizz").
accept("application/json").get(ClientResponse.class);
Fizz fizz1 = response.getEntity(Fizz.class);
System.out.println(fizz1);
}
以下是我用于测试的其他代码
@Path("/fizz")
public class FizzResource {
@POST
@Consumes("application/json")
public Response postFizz(Fizz fizz) {
System.out.println("==== Created Fizz ===");
System.out.println(fizz);
System.out.println("=====================");
return Response.created(null).build();
}
@GET
@Produces("application/json")
public Response getFizz() {
Fizz fizz = new Fizz(1, "fizz");
return Response.ok(fizz).build();
}
}
服务器配置
ResourceConfig resourceConfig = new PackagesResourceConfig("test.json.pojo");
resourceConfig.getFeatures().put(
JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
客户端配置
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
Client client = Client.create(clientConfig);
r = client.resource(Main.BASE_URI);
// r = WebResource
答案 2 :(得分:0)
如果你包括(假设你使用maven)
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
然后您将自动转换而无需设置任何内容。您可以编写如下函数:
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Activity createActivity(@Valid Activity activity) {
return activityDAO.createActivity(vuser,activity);
}