Java Jersey Rest-JsonMappingException:找不到适合类型[简单类型,类]的构造函数

Java Jersey Rest-JsonMappingException:找不到适合类型[简单类型,类]的构造函数,java,json,api,rest,jersey,Java,Json,Api,Rest,Jersey,我使用jax-rs和jersey创建了一个restapi。我想从RESTAPI中的外部库返回JSON格式的对象。但是,此对象没有默认构造函数,这会导致以下异常: Caused by: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class ....EncryptionToken]: can not instantiate from JSON

我使用jax-rs和jersey创建了一个restapi。我想从RESTAPI中的外部库返回JSON格式的对象。但是,此对象没有默认构造函数,这会导致以下异常:

Caused by: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class ....EncryptionToken]: can not instantiate from JSON object (need to add/enable type information?) 
通过RESTAPI返回此对象的最佳方式是什么

这是我的REST API实现:

@GET
@Produces(MediaType.APPLICATION_JSON)
public javax.ws.rs.core.Response get( //
            @QueryParam("etkIdentifierType") String etkIdentifierType, //
            @QueryParam("etkIdentifierValue") String etkIdentifierValue, //
            @QueryParam("applicationId") String applicationId) {
    LOG.info("GET Request: Lookup encryption token for etkIdentifierType [" + etkIdentifierType + "], etkIdentifierValue [" + etkIdentifierValue + "] and applicationId [" + applicationId + "]");
    final EncryptionToken token = etkService.getETK(etkIdentifierType, etkIdentifierValue, applicationId);
    return Response.ok(token).build();
}
加密类来自我无法修改的外部库。我首先尝试用相同的变量构造一个自己的对象并返回它,但并非所有的getter方法都是公共的

这是EncryptionToken类:

package ...;

public class EncryptionToken {
    private java.security.cert.X509Certificate encrCert;
    private byte[] encoded;
    private java.security.cert.X509Certificate authCert;
    private java.security.cert.X509Certificate etkRaCert;
    private java.util.List<java.security.cert.X509Certificate> caCertChain;

    EncryptionToken(byte[] encoded, java.security.cert.X509Certificate encrCert, java.security.cert.X509Certificate authCert, java.util.List<java.security.cert.X509Certificate> caCertChain, java.security.cert.X509Certificate etkRaCert) { /* compiled code */ }

    public final byte[] getEncoded() { /* compiled code */ }

    public final byte[] getBase64Encoded() { /* compiled code */ }

    public final java.security.cert.X509Certificate getCertificate() { /* compiled code */ }

    public final java.security.cert.X509Certificate getAuthenticationCertificate() { /* compiled code */ }

    java.util.List<java.security.cert.X509Certificate> getCaCertChain() { /* compiled code */ }

    java.security.cert.X509Certificate getEtkRaCert() { /* compiled code */   }
}

但由于我无法实例化EncryptionToken(没有默认构造函数,可用的构造函数是nog public),我不知道如何解决这个问题…

您可以实现自定义
JsonSerializer
对象并将其注册到Jackson上下文中

public class EncryptionTokenSerializer extends JsonSerializer<EncryptionToken> {
    @Override
    public void serialize(EncryptionToken value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException {
        jgen.writeStartObject();
        jgen.writeBinaryField("encoded", value.getEncoded());
        jgen.writeBinaryField("base64Encoded", value.getBase64Encoded());
        jgen.writeEndObject();
    }
}
公共类EncryptionTokenSerializer扩展JsonSerializer{
@凌驾
public void serialize(EncryptionToken值、JsonGenerator jgen、SerializerProvider提供程序)
抛出IOException{
jgen.writeStartObject();
writeBinaryField(“encoded”,value.getEncoded());
writeBinaryField(“base64Encoded”,value.getBase64Encoded());
jgen.writeEndObject();
}
}

如果您想知道如何在上下文中注册序列化程序,请检查

嘿,我在我的机器上尝试了您的代码。我在执行它时没有任何问题。 这给了我正确的结果。 能否提供方法“etkService.getETK()”的实现以及“etkService”的声明和定义。这可能会导致一些问题

最终EncryptionToken令牌=etkService.getETK(etkIdentifierType,etkIdentifierValue,applicationId)


并且不必为POJO提供反序列化程序

将默认(非参数)构造函数添加到EncryptionToken。也许Jackson会创建一个空实例,然后通过getter放置属性/setters@bigdestroyer这是我的第一个想法,但不幸的是,我无法访问EncryptionToken类,因为它位于一个外部jar中,我无法从中修改内容。我的另一个想法是扩展这个类,但是构造函数是包保护的。第三种解决方案是使用相同的变量创建一个新类并传递它,但由于并非所有getter都是公共的,而且我使用的其他方法都使用EncryptionToken对象,所以我无法在对象之间编写一个合适的映射器……感谢您的示例。这是非常有希望的。但是,如何将此自定义序列化程序注册到jackson上下文中?我会用
@JsonSerialize(using=EncryptionTokenSerializer.class)
注释该类,但由于我没有访问EncryptionToken类的权限,我无法这样做…我设法通过了EncryptionTokenSerializer(在调试模式下),但不幸的是,我仍然收到投诉,EncryptionToken类缺少默认构造函数
com.sun.jersey.api.client.ClientHandlerException:org.codehaus.jackson.map.JsonMappingException:找不到适合类型的构造函数[简单类型,类be.fgov.ehealth.etee.crypto.encrypt.EncryptionToken]:无法在处从JSON对象实例化(需要添加/启用类型信息吗?)[来源:sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@77da01;行:1,列:2]
public class EncryptionTokenSerializer extends JsonSerializer<EncryptionToken> {
    @Override
    public void serialize(EncryptionToken value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException {
        jgen.writeStartObject();
        jgen.writeBinaryField("encoded", value.getEncoded());
        jgen.writeBinaryField("base64Encoded", value.getBase64Encoded());
        jgen.writeEndObject();
    }
}