簡體   English   中英

當objectMapper.readValue(str,MyObj.class);工作時,.readEntity(MyObj.class);失敗的原因

[英]how come `.readEntity(MyObj.class)` fails while `objectMapper.readValue(str, MyObj.class);` works

我有這個代碼

import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Map;
/**
 * Created by eladb on 9/6/16.
 */
public class DeploymentClient {

    private CommonClient commonClient;


    String appName = "topic-test-publisher";


    public DeploymentClient(String url, InputStream clientSecretFile) {
        commonClient = new CommonClient(url, clientSecretFile);
    }

    public VersionOld getCurrentConfigVersion(String project, String subDir) throws Exception {
        VersionOld version = commonClient.authorizedRequestBuilder(commonClient.webTarget
                .path("/apps/get_current_version/default/"+appName+"/"+appName)
                .queryParam("object_type", "app"))
                .accept(MediaType.APPLICATION_JSON_TYPE)
                .get(ClientResponse.class)
                .readEntity(VersionOld.class);

        return null;
    }
}

這給了我一個例外:

javax.ws.rs.client.ResponseProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Map type [map type; class javax.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.Object]]]

at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:806)
at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:700)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:696)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316)

但是這段代碼有效:

import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Map;
/**
 * Created by eladb on 9/6/16.
 */
public class DeploymentClient {

    private CommonClient commonClient;


    String appName = "topic-test-publisher";


    public DeploymentClient(String url, InputStream clientSecretFile) {
        commonClient = new CommonClient(url, clientSecretFile);
    }

    public VersionOld getCurrentConfigVersion(String project, String subDir) throws Exception {
        String str = commonClient.authorizedRequestBuilder(commonClient.webTarget
                .path("/apps/get_current_version/default/"+appName+"/"+appName)
                .queryParam("object_type", "app"))
                .accept(MediaType.APPLICATION_JSON_TYPE)
                .get()
                .readEntity(String.class);



        VersionOld v =  foo(str);
        return null;
    }

    public VersionOld foo(String str){
            ObjectMapper objectMapper = new ObjectMapper();
        VersionOld v = null;
        try {
            v = objectMapper.readValue(str, VersionOld.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return v;
    }
}

在這兩種情況下,http響應均為:

str = {"versions": {"ap": "Not Set", "am": "topic-test-publisher-1.0.16", "il": "topic-test-publisher-1.0.16", "row": "topic-test-publisher-1.0.49"}, "provider": "gce"}

這段代碼如何運作正常?

邏輯不一樣嗎?

只需在客戶端代碼中用javax.ws.rs.core.Response替換ClientResponse即可,或者根本不使用任何參數。

    VersionOld version = commonClient.authorizedRequestBuilder(commonClient.webTarget
            .path("/apps/get_current_version/default/"+appName+"/"+appName)
            .queryParam("object_type", "app"))
            .accept(MediaType.APPLICATION_JSON_TYPE)
            .get(javax.ws.rs.core.Response.class)//or get().readEntity(VersionOld.class);
            .readEntity(VersionOld.class);

我相信您使用了org.glassfish.jersey.client.ClientResponse,但返回的資源可能是javax.ws.rs.core.Response (我也遇到了)

我用以下服務器端代碼進行了測試

@GET
@Path("/us")
@Produces(MediaType.APPLICATION_JSON)
public Response getJson() { //javax.ws.rs.core.Response
    VersionOld vo = new VersionOld();
    vo.versions.put("ap", "Not set");
    vo.versions.put("am", "topic-test-publisher-1.0.16");
    vo.versions.put("il", "topic-test-publisher-1.0.16");
    vo.versions.put("row", "topic-test-publisher-1.0.49");
    vo.provider = "gce";


    return Response.status(200).entity(vo).build();
}

POJO被定義為

public class VersionOld {

  //public variables but you can use getters/setters
public Map<String,String> versions = new HashMap<>();
public String provider;

public VersionOld(){}
  }  

輸出是

Msg: topic-test-publisher-1.0.16
Msg: topic-test-publisher-1.0.49

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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