簡體   English   中英

使用Jackson傳遞POJO作為實體的Jersey / JAX-RS客戶端

[英]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>

該模塊將具有所需的MessageBodyReaderMessageBodyWriter ,它們將在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM