[英]Jersey/JAX-RS clients that use Jackson to pass POJOs as entities
我正在嘗試使用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
類已經使用正確的Jackson注釋( JsonProperty
等)進行了注釋。
有任何想法嗎?
您可以使用Jackson的ObjectMapper:
final ObjectMapper mapper = new ObjectMapper();
mapper.readValue(response.getEntity(String.class), Fizz.class);
只要正確注釋了Fizz,它就可以滿足您的要求。
還有其他選擇,通常涉及實現自定義提供程序。
您正在使用Jersey 1.x,因此請查看JSON / POJO支持的用戶指南
第一件事:我們需要確保您擁有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);
}
}
查看其他部署選項
客戶端配置
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
如果包含(假設您使用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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.