Jersey Rest - JsonMappingException:找不到类型[simple type,class]的合适构造函数

时间:2015-02-18 11:07:35

标签: java json api rest jersey

我使用jax-rs和jersey创建了一个REST API。我想从REST API中的外部库返回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?) 

通过REST API返回此对象的最佳方法是什么?

这是我的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();
}

Encryption类来自我无法修改的外部库。我首先尝试用相同的变量构造一个自己的对象并返回它,但并不是所有的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 */   }
}

编辑:我认为对于我的情况我需要一个反序列化器。代码在以下行中失败:

final EncryptionToken encryptionToken = response.getEntity(EncryptionToken.class);

但是因为我无法实例化一个EncryptionToken(没有默认的构造函数和可用的构造函数是公共的)我不知道如何解决这个问题......

2 个答案:

答案 0 :(得分:1)

您可以实现自定义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();
    }
}

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

答案 1 :(得分:0)

嘿,我在我的机器上尝试了你的代码。我没有遇到任何问题。 它给了我正确的结果。 你能提供方法实施&#39; etkService.getETK()&#39;和宣言&amp;定义&#39; etkService&#39;。由此可能会出现一些问题。

final EncryptionToken token = etkService.getETK(etkIdentifierType,etkIdentifierValue,applicationId);

并且没有必要为您的POJO提供解串器