相关疑难解决方法(0)

如何在自定义序列化程序中访问默认的jackson序列化

我想创建一个自定义序列化程序,它可以完成一些工作,然后将其余部分用于默认序列化.

例如:

@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
  ...
}

public class MyClassSerializer extends JsonSerializer<MyClass> {
    @Override
    public void serialize(MyClass myClass, JsonGenerator generator, 
                          SerializerProvider provider) 
            throws JsonGenerationException, IOException {
        if (myClass.getSomeProperty() == someCalculationResult) {
            provider.setAttribute("special", true);
        }
        generator.writeObject(myClass);
    }  
}
Run Code Online (Sandbox Code Playgroud)

有了为聚合对象创建其他自定义序列化程序的想法,这些序列化程序根据'speical'属性值表现不同.但是,上面的代码不起作用,因为毫无疑问会进入无限递归.

有没有办法告诉杰克逊在设置属性后使用默认序列化?我真的不想枚举像许多自定义序列化程序一样的所有属性,因为类相当复杂,我不想每次更改类时都要对序列化程序进行双重维护.

java json jackson

21
推荐指数
2
解决办法
2万
查看次数

如何从JsonParser获取底层字符串(Jackson Json)

浏览文档和源代码,我没有看到明确的方法来做到这一点.好奇,如果我错过了什么.

假设我从服务器响应中收到一个InputStream.我从这个InputStream创建一个JsonParser.预计服务器响应是包含有效JSON的文本,例如:

{"iamValidJson":"yay"}

但是,如果响应最终是无效的JSON或根本不是JSON,例如:

Some text that is not JSON

JsonParser最终会抛出异常.在这种情况下,我希望能够Some text that is not JSON从JsonParser中提取底层的无效文本" ",以便它可以用于其他目的.

我无法将其从InputStream中拉出来,因为它不支持重置,并且JsonParser的创建会消耗它.

有没有办法做到这一点?

java android json inputstream jackson

18
推荐指数
3
解决办法
2万
查看次数

如何委托杰克逊的自定义反序列化器中的默认反序列化?

假设我正在为某个类编写自定义序列化,但是希望使用默认方法处理其中一个字段.

怎么做?

虽然序列化我们有JsonGenerator#writeObjectField().

但是反序列化的相应方法是什么?

请注意以下代码:

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.IOException;
import java.util.Objects;

public class TryDelegate {

   public static class MyOuterClassSerializer extends JsonSerializer<MyOuterClass> {

      @Override
      public void serialize(MyOuterClass value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
         gen.writeStartObject();

         gen.writeObjectField("inner", value.getInner());

         gen.writeEndObject();
      }
   }

   public static class MyOuterClassDeserializer extends JsonDeserializer<MyOuterClass> {
      @Override
      public MyOuterClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {


         MyOuterClass ans = new MyOuterClass();

         JsonToken token;

         token = p.getCurrentToken();
         if( token != …
Run Code Online (Sandbox Code Playgroud)

java serialization json jackson

14
推荐指数
1
解决办法
5246
查看次数

JacksonPolymorphicDeserialization:JsonMappingException

我有一个父类参数,它有2个子类ComboParameterIntegerParameter

@JsonSubTypes({
    @JsonSubTypes.Type(value = IntegerParameter.class, name = "integerParam"),
    @JsonSubTypes.Type(value = ComboParameter.class, name = "comboParam")
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.WRAPPER_OBJECT)
 public abstract class Parameter {
String regEx;
}


@JsonTypeName("integerParam")
public class IntegerParameter extends Parameter {
}

@JsonTypeName("comboParam")
public class ComboParameter extends Parameter {
List<String> values;
}
Run Code Online (Sandbox Code Playgroud)

我有一个具有属性参数的类

class A {
@JsonUnwrapped
Parameter parameter;
}
Run Code Online (Sandbox Code Playgroud)

对象的序列化A抛出异常

com.fasterxml.jackson.databind.JsonMappingException:未包装的属性需要使用类型信息:无法在不禁用的情况下序列化 SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS

如果我删除注释,@JsonUnwrapped我会有一个像那样的json

{
     parameter:{
          integerParam:{
               regEx: regExVal
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

而我需要的是像这样的json:

{ …
Run Code Online (Sandbox Code Playgroud)

serialization json spring-mvc jackson deserialization

9
推荐指数
1
解决办法
976
查看次数

Jackson JSON在序列化之前修改对象

我希望在序列化之前修改对象.我想编写一个自定义序列化程序来解析对象,然后将其传递给默认对象序列化程序.

这就是我所拥有的:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

/**
 *
 * @author Me
 */
public class PersonSerializer extends JsonSerializer<Person>{

    @Override
    public void serialize(Person value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {

        //This returns a modified clone of Person value.
        Person safePerson = PrivacyService.getSafePerson(value);

        provider.defaultSerializeValue(safePerson, jgen);

    }

}
Run Code Online (Sandbox Code Playgroud)

但这只是一个无限循环.我也尝试过:

provider.findTypedValueSerializer(Person.class, true, null).serialize(safePerson, jgen, provider);
Run Code Online (Sandbox Code Playgroud)

这可行,但它不解析对象中的任何字段.

我也试过使用a @JsonFilter但它非常重,并且我的加载时间是六倍.

救命!谢谢!

java serialization json jackson

7
推荐指数
3
解决办法
7113
查看次数

Jackson Deserializer 委托给下一个适用的解串器

我有一个外部服务,用于查询一些数据。数据将采用两种格式之一(第一种是“遗留”,但需要支持):

{
    "foo": "John Smith"
}
Run Code Online (Sandbox Code Playgroud)

或者

{
    "foo": {
        "name": "John Smith",
        "bar": "baz"
    }
}
Run Code Online (Sandbox Code Playgroud)

我想映射到以下 POJO:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Outer {

    private Foo foo;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Foo {

        String name;
        String bar;

    }

}
Run Code Online (Sandbox Code Playgroud)

第二种格式(foo是一个对象)中的数据应该像任何其他 POJO 一样反序列化,但是给定第一种格式(foo是字符串)中的数据,要将其转换为 的实例Foo,我想调用new Foo(<foo>, null). 为此,我创建了一个自定义解串器(@JsonComponent意味着这个解串器将ObjectMapper通过 JacksonModule接口在 spring 中注册到某种全局):

@JsonComponent
public class FooDeserializer extends JsonDeserializer<Outer.Foo> {

    @Override
    public Outer.Foo deserialize(JsonParser parser, DeserializationContext …
Run Code Online (Sandbox Code Playgroud)

java json jackson json-deserialization spring-boot

6
推荐指数
1
解决办法
1884
查看次数

用于抽象类及其子类型的StdDeserializer

假设有一个具有属性a和三个非抽象子类B,C和D的抽象类A。B没有其他属性,C包含属性c,D包含属性c和d。

我希望将StdDeserializer子类化为抽象类A,以便能够基于要反序列化的属性的存在来决定选择哪个子类。

我之前是从Codehaus发行的Jackson版本中做到这一点的,并且使用以下实现工作正常:

class AbstractADeserializer extends StdDeserializer<A> {
    AbstractADeserializer () {
        super(A.class);
    }

    @Override
    public A deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = (ObjectNode) mapper.readTree(jp);
        Class<? extends A> requestClass = null;

        // root.getFieldNames() is an iterator over all field names
        JsonNode cValue = root.findValue("c");
        JsonNode dValue = root.findValue("d");

        /*
         * Check for existence of required fields and choose the
         * corresponding request class.
         */
        logger.debug(Boolean.toString(c != null)); …
Run Code Online (Sandbox Code Playgroud)

java json jackson

5
推荐指数
1
解决办法
2482
查看次数

在 POST/PUT 期间将所有对象作为其 id 或嵌入整个对象的单个自定义反序列化器

@Entity
public Product {
   @Id
   public int id;

   public String name;

   @ManyToOne(cascade = {CascadeType.DETACH} )
   Category category

   @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH} )
   Set<Category> secondaryCategories;


}
Run Code Online (Sandbox Code Playgroud)

和这个实体:

@Entity
public Category {
   @Id
   public int id;

   public String name;
}
Run Code Online (Sandbox Code Playgroud)

我希望能够使用 json 发送 POST

{ name: "name", category: 2, secondaryCategories: [3,4,5] }从客户端

并且能够像这样反序列化:

{ name: "name", category: {id: 2 }, secondaryCategories: [{id: 3}, {id: 4}, {id: 5}] }
Run Code Online (Sandbox Code Playgroud)

如果它被发送为

 { name: "name", category: {id: 2 }, secondaryCategories: [{id: 3}, …
Run Code Online (Sandbox Code Playgroud)

spring json jackson spring-data spring-data-jpa

5
推荐指数
1
解决办法
2923
查看次数

使用 Jackson 序列化时有条件地跳过对象

我有一个像这样的课程

interface IHideable {
   boolean isHidden();
}

class Address implements IHideable {
    private String city;
    private String street;
    private boolean hidden;
}

class PersonalInfo implements IHideable {
    private String name;
    private int age;
    private boolean hidden;
}
Run Code Online (Sandbox Code Playgroud)

我想在我的网络服务中序列化 IHideable 列表;但过滤掉隐藏字段设置为 true 的任何对象。

基本上给出了一个对象列表,例如

[
{'city 1','street 1',false},
{'city 2','street 2',true},
{'city 3','street 3',false}
]
Run Code Online (Sandbox Code Playgroud)

我想要的输出为

[
  {
    city:'city 1',
    street:'street 1'
  },
  {
    city:'city 3',
    street:'street 3'
  }
]
Run Code Online (Sandbox Code Playgroud)

我尝试了以下实现

class ItemSerializer extends JsonSerializer<IHideable> {  
    @Override
    public void serialize(IHideable value, …
Run Code Online (Sandbox Code Playgroud)

java serialization json jackson

4
推荐指数
1
解决办法
6956
查看次数

使用 Jackson 和 Spring-Boot 将 Base64 编码的 JSON 解码为 POJO

我有一个这样的请求

{
    "varA"  : "A",
    "varB" : "TCFNhbiBKb3NlMRgwFgYDVQQK"
}
Run Code Online (Sandbox Code Playgroud)

其中 keyvarB是一个 base64 编码的 JSON 字符串。像这样的东西:

{
    "nestedVarB1": "some value here",
    "nestedVarB2" : "some other value here"
}
Run Code Online (Sandbox Code Playgroud)

我想将它转换成一些 POJO,如下所示:

@Data
public class MyRequest {
    private String varA;
    private B varB;
}

@Data
public class B {
    private String nestedVarB1;
    private String nestedVarB2;
}
Run Code Online (Sandbox Code Playgroud)

我经历了几个关于堆栈溢出的解决方案,例如thisthisMyRequest ,但我想通过编写某种 Jackson 反序列化器将 JSON 直接转换为类型的对象。

如何直接将 JSON 转换为MyRequest使用 Jackson 和 Spring Boot?

笔记:

  1. POJOMyRequestB非常大, …

java json spring-mvc jackson spring-boot

4
推荐指数
1
解决办法
1万
查看次数

如何向用于支持 Jackson 中多态反序列化的鉴别器属性添加别名?

我有一个标准的多态类型Shape,我可以使用标准@JsonTypeInfo机制对其进行多态反序列化:

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

public class DiscriminatorAliasTest {

  @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
  @JsonSubTypes({
      @JsonSubTypes.Type(value = Square.class, name = "square"),
      @JsonSubTypes.Type(value = Circle.class, name = "circle")
  })
  static abstract class Shape {
    abstract public String name();
  }

  static class Square extends Shape {
    @JsonProperty("A")
    public float width;

    @Override
    public String name() { return "square"; }
  }

  static class …
Run Code Online (Sandbox Code Playgroud)

java json jackson

4
推荐指数
1
解决办法
766
查看次数

杰克逊用另一个字段的哈希添加自定义字段

所以,标题基本上描述了我需要的东西.比如说,要序列化的bean看起来像这样:

public class SomeBean {
    public String someString;
}
Run Code Online (Sandbox Code Playgroud)

我希望Jackson 像这样序列化SomeBean的一个实例:

{
    someString: '<the value>',
    __hash_someString: '<a proprietary hash of <the value>>'
}
Run Code Online (Sandbox Code Playgroud)

此功能应该是通用的.我不想为SomeBean编写特定的序列化程序,因为这需要在多个位置进行.将" __hash_someString " 添加到类本身不是一个选项,因为它会污染模型.

履行

我希望杰克逊能正常处理豆子.但是当遇到特定的注释(@GenerateHash)时,它应该像之前一样向对象添加另一个字段.所以它想这样:

public class SomeBean {
    @GenerateHash
    public String someString;
}
Run Code Online (Sandbox Code Playgroud)

这条路到目前为止

有很多类似的主题,但没有一个尝试这样的事情.我并没有真正进入Jackson Serialization的内部工作,但似乎你只能选择修改一个整体的对象.我还没有找到一种方法来拦截字段的序列化过程,只有该字段的值.

我试图使用BeanSerializerModifier实现这一点,并尝试使用@Serializer.但是,我通常最终会陷入无限循环.

我咨询的资源是(不限于):

简而言之, 我怎样才能让杰克逊序列化

public class SomeBean {
    @GenerateHash
    public String someString;

    public String unaffectedString;
}
Run Code Online (Sandbox Code Playgroud)

对此:

{
    someString: '<the value>',
    __hash_someString: '<a …
Run Code Online (Sandbox Code Playgroud)

java hash serialization json jackson

3
推荐指数
1
解决办法
1354
查看次数

使用 Jackson 自定义反序列化:扩展默认反序列化器

我想通过扩展默认值并在其后设置更多值来制作我自己的解串器:

simplified code:
public class Dto {
    public String originalJsonString;
}

public MyFooDto extends Dto {
    public String myField;
}



@Bean
public ObjectMapper deserializingObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    JavaTimeModule javaTimeModule = new JavaTimeModule();
    javaTimeModule.addDeserializer(MyFooDto.class, new JsonDtoDeserializer<>());
    objectMapper.registerModule(javaTimeModule);
    return objectMapper;
}
// or maybe instead of the Beam just @JsonDeserialize(using = JsonDtoDeserializer.class) before MyFooDto?


public class JsonDtoDeserializer<T extends Dto> extends StdDeserializer<T> {
// or maybe extends JsonDeserializer? or UntypedObjectDeserializer? or UntypedObjectDeserializer.Vanilla?

    public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException …
Run Code Online (Sandbox Code Playgroud)

java spring jackson json-deserialization spring-boot

1
推荐指数
1
解决办法
5578
查看次数