配置jackson使用单arg构造函数 [英] Configure jackson to use single-arg constructor

查看:571
本文介绍了配置jackson使用单arg构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个不可变对象 SimpleGrantedAuthority 来自spring,它没有no-arg构造函数。相反,它是一个只有1个单arg构造函数的不可变对象:

  public SimpleGrantedAuthority(String role){
Assert.hasText(角色,授权的权限文本表示是必需的);
this.role = role;
}

我正在尝试将字符串反序列化为此对象而我不有权访问此文件的源代码。这是我得到的例外:

 引起:com.fasterxml.jackson.databind.JsonMappingException:无法构造org的实例。 springframework.security.core.authority.SimpleGrantedAuthority:找不到合适的构造函数,无法从Object值反序列化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?)
at [Source:java.util .zip.GZIPInputStream @ e1fb329; line:7,column:7](通过参考链:com.nemesis.platform.facade.email.data.EnrichedEmailMessageContextData [customer] - > com.nemesis.platform.facade.user.data.EnrichedUserDetails [authority ] - > java.util.ArrayList [0])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind。 DeserializationContext.instantiationException(DeserializationContext.java:1456)

就像我说的我没有源代码而且我无法添加 @JsonCreator 注释,所以我想知道如何配置jackson来理解要使用的正确构造函数。喜欢的东西:

 模块模块=新的SimpleModule(MyModule){

@覆盖
public void setupModule(Module.SetupContext context){
context.addAbstractTypeResolver(new SimpleAbstractTypeResolver()。addMapping(GrantedAuthority.class,SimpleGrantedAuthority.class));
}
};

谢谢



编辑



我尝试了Shashank的建议,所以我创建了这个课程:

 抽象类SimpleGrantedAuthorityMixIn {
@JsonCreator
SimpleGrantedAuthorityMixIn(@JsonProperty(authority)字符串权限){
}
}

然后我这样注册:

 模块模块= new SimpleModule(SamplestoreModule){

@Override
public void setupModule(Module.SetupContext context){
context.addAbstractTypeResolver(new SimpleAbstractTypeResolver() .addMapping(GrantedAuthority.class,SimpleGrantedAuthority.class));
context.setMixInAnnotations(SimpleGrantedAuthority.class,SimpleGrantedAuthorityMixIn.class);
}
};

objectMapper.registerModule(module);
objectMapper.addMixIn(SimpleGrantedAuthority.class,SimpleGrantedAuthorityMixIn.class);

但我仍然看到相同的例外。

mixin 这将为jackson提供所有元数据而不修改实际的pojo。



第三方类:

  public class SingleArgConstructor {
public int getN(){
return n;
}
int n;

public SingleArgConstructor(int n){
this.n = n;
}

@Override
public String toString(){
returnSingleArgConstructor {+
n =+ n +
'}';
}

}

代码中的Mixin:

 抽象类MixIn {
@JsonCreator
MixIn(@JsonProperty(n)int n){}
}

配置映射器:

  ObjectMapper objectMapper = new ObjectMapper(); 
objectMapper.addMixIn(SingleArgConstructor.class,MixIn.class);

阅读价值:

  System.out.println(objectMapper.readValue({\n\:10},SingleArgConstructor.class)); 

我希望这会有所帮助。



EDITED
分享完整代码:



抽象类

  / ** 
*由shashankt于2016年12月6日创建。
* /
公共抽象类AbstractArgsConstructor {
int n;
public AbstractArgsConstructor(int n){
this.n = n;
}

}



具体实现

  import com.fasterxml.jackson.databind.Module; 
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;

/ **
*由shashankt于2016年12月4日创建。
* /
公共类SingleArgConstructor扩展AbstractArgsConstructor {
public SingleArgConstructor(int n){
super(n);
}

public int getN(){
return n;
}




public static void main(String [] args)抛出IOException {
模块模块= new SimpleModule(SamplestoreModule ){

@Override
public void setupModule(Module.SetupContext context){
context.addAbstractTypeResolver(new SimpleAbstractTypeResolver()。addMapping(AbstractArgsConstructor.class,SingleArgConstructor.class) );
}
};
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
objectMapper.addMixIn(SingleArgConstructor.class,Mixin.class);
System.out.println(objectMapper.getDeserializationConfig()。findMixInClassFor(AbstractArgsConstructor.class));
System.out.println(objectMapper.getDeserializationConfig()。findMixInClassFor(SingleArgConstructor.class));

SingleArgConstructor pojo = new SingleArgConstructor(10);
System.out.println(objectMapper.readValue({\p\:10},AbstractArgsConstructor.class));
}

@Override
public String toString(){
returnSingleArgConstructor {+
n =+ n +
'}';
}

}

with mixin

  import com.fasterxml.jackson.annotation.JsonCreator; 
import com.fasterxml.jackson.annotation.JsonProperty;

/ **
*由shashankt于2016年12月4日创建。
* /

抽象类Mixin {
@JsonCreator
Mixin(@JsonProperty(p)int n){}
}

输出

  null 
class Mixin
SingleArgConstructor {n = 10}

处理完成后退出代码0


I have an immutable object SimpleGrantedAuthority from spring which does not have a no-arg constructor. Instead it is an immutable object with only 1 single-arg constructor like this:

public SimpleGrantedAuthority(String role) {
    Assert.hasText(role, "A granted authority textual representation is required");
    this.role = role;
}

I'm trying to deserialize a string to this object and I don't have access to the source code of this file. Here's the exception I get:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.security.core.authority.SimpleGrantedAuthority: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.util.zip.GZIPInputStream@e1fb329; line: 7, column: 7] (through reference chain: com.nemesis.platform.facade.email.data.EnrichedEmailMessageContextData["customer"]->com.nemesis.platform.facade.user.data.EnrichedUserDetails["authorities"]->java.util.ArrayList[0])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)

Like I said I don't have the source code and I cannot add the @JsonCreator annotation, so I'm wondering how to configure jackson to understand the correct constructor to use. Something in the likes of:

    Module module = new SimpleModule("MyModule") {

        @Override
        public void setupModule(Module.SetupContext context) {
            context.addAbstractTypeResolver(new SimpleAbstractTypeResolver().addMapping(GrantedAuthority.class, SimpleGrantedAuthority.class));
        }
    };

Thank you

EDIT

I tried the suggestion of Shashank so I created this class:

abstract class SimpleGrantedAuthorityMixIn {
    @JsonCreator
    SimpleGrantedAuthorityMixIn(@JsonProperty("authority") String authority) {
    }
}

and then I registered it like this:

    Module module = new SimpleModule("SamplestoreModule") {

        @Override
        public void setupModule(Module.SetupContext context) {
            context.addAbstractTypeResolver(new SimpleAbstractTypeResolver().addMapping(GrantedAuthority.class, SimpleGrantedAuthority.class));
            context.setMixInAnnotations(SimpleGrantedAuthority.class, SimpleGrantedAuthorityMixIn.class);
        }
    };

    objectMapper.registerModule(module);
    objectMapper.addMixIn(SimpleGrantedAuthority.class, SimpleGrantedAuthorityMixIn.class);

but I still see the same exception.

解决方案

You need to use mixin which will provide all meta data to jackson without modifying actual pojo.

Third party class:

public class SingleArgConstructor {
   public int getN() {
     return n;
   }
   int n;

   public SingleArgConstructor( int n) {
      this.n = n;
   }

   @Override
   public String toString() {
      return "SingleArgConstructor{" +
            "n=" + n +
            '}';
   }

}

Mixin in you code:

abstract class MixIn {
  @JsonCreator
  MixIn(@JsonProperty("n") int n) { }
}

Configuring mapper:

 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.addMixIn(SingleArgConstructor.class,MixIn.class);

Reading value:

  System.out.println(objectMapper.readValue("{\"n\":10}",SingleArgConstructor.class));

I hope this helps.

EDITED Sharing complete code:

Abstract class

/**
 * Created by shashankt on 6/12/16.
*/
public abstract class  AbstractArgsConstructor {
   int n;
   public AbstractArgsConstructor( int n) {
       this.n = n;
   }

}

Concrete implementation

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;

/**
 * Created by shashankt on 4/12/16.
*/
 public class SingleArgConstructor extends AbstractArgsConstructor{
 public SingleArgConstructor(int n) {
    super(n);
 }

 public int getN() {
    return n;
 }




 public static void main(String[] args) throws IOException {
    Module module = new SimpleModule("SamplestoreModule") {

        @Override
        public void setupModule(Module.SetupContext context) {
            context.addAbstractTypeResolver(new SimpleAbstractTypeResolver().addMapping(AbstractArgsConstructor.class, SingleArgConstructor.class));
        }
     };
     ObjectMapper objectMapper = new ObjectMapper();
     objectMapper.registerModule(module);
     objectMapper.addMixIn(SingleArgConstructor.class,Mixin.class);
       System.out.println(objectMapper.getDeserializationConfig().findMixInClassFor(AbstractArgsConstructor.class));
       System.out.println(objectMapper.getDeserializationConfig().findMixInClassFor(SingleArgConstructor.class));

    SingleArgConstructor pojo = new SingleArgConstructor(10);
    System.out.println(objectMapper.readValue("  {\"p\":10}",AbstractArgsConstructor.class));
  }

 @Override
 public String toString() {
     return "SingleArgConstructor{" +
             "n=" + n +
             '}';
 }

}

with mixin

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Created by shashankt on 4/12/16.
*/

abstract class Mixin {
  @JsonCreator
  Mixin(@JsonProperty("p") int n) { }
}

Output

null
class Mixin
SingleArgConstructor{n=10}

Process finished with exit code 0

这篇关于配置jackson使用单arg构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆