Java 使用jackson和spring boot将base64编码的JSON解码为POJO

Java 使用jackson和spring boot将base64编码的JSON解码为POJO,java,json,spring-mvc,spring-boot,jackson,Java,Json,Spring Mvc,Spring Boot,Jackson,我有一个这样的要求 { "varA" : "A", "varB" : "TCFNhbiBKb3NlMRgwFgYDVQQK" } 其中keyvarB是一个base64编码的JSON字符串。大概是这样的: { "nestedVarB1": "some value here", "nestedVarB2" : "some other value here" } @Data public class MyRequest { private String v

我有一个这样的要求

{
    "varA"  : "A",
    "varB" : "TCFNhbiBKb3NlMRgwFgYDVQQK"
}
其中key
varB
是一个base64编码的JSON字符串。大概是这样的:

{
    "nestedVarB1": "some value here",
    "nestedVarB2" : "some other value here"
}
@Data
public class MyRequest {
    private String varA;
    private B varB;
}

@Data
public class B {
    private String nestedVarB1;
    private String nestedVarB2;
}
我想把它转换成一些POJO,如下所示:

{
    "nestedVarB1": "some value here",
    "nestedVarB2" : "some other value here"
}
@Data
public class MyRequest {
    private String varA;
    private B varB;
}

@Data
public class B {
    private String nestedVarB1;
    private String nestedVarB2;
}
我在堆栈溢出上使用了几种解决方案,如和,但我想通过编写某种Jackson反序列化程序,将JSON直接转换为类型为
MyRequest
的对象

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

注:

  • POJO
    MyRequest
    B
    非常大,而且
    B
    可以进一步嵌套,因此手动执行将是一项艰巨的任务
  • 我无法控制请求,它来自第三方。因此,无法更改请求的格式

  • 我做了一些实验,这里有一个简单的Jackson反序列化程序,应该适合你

    反序列化程序实现ContextualDeserializer接口以访问实际的bean属性(例如
    varB
    )。检测正确的结果类型是必要的,因为反序列化器本身可以附加到任何类型的字段

    import com.fasterxml.jackson.core.JsonParser;
    导入com.fasterxml.jackson.core.JsonProcessingException;
    导入com.fasterxml.jackson.databind.*;
    导入com.fasterxml.jackson.databind.deser.ContextualDeserializer;
    导入com.fasterxml.jackson.databind.exc.InvalidFormatException;
    导入java.io.IOException;
    导入java.util.Base64;
    公共类Base64反序列化程序扩展JsonDeserializer实现ContextualDeserializer{
    私有类resultClass;
    @凌驾
    公共JsonDeserializer createContext(反序列化上下文,BeanProperty属性)抛出JsonMappingException{
    this.resultClass=property.getType().getRawClass();
    归还这个;
    }
    @凌驾
    公共对象反序列化(JsonParser解析器、反序列化上下文)引发IOException、JsonProcessingException{
    String value=parser.getValueAsString();
    Base64.Decoder Decoder=Base64.getDecoder();
    试一试{
    ObjectMapper ObjectMapper=新的ObjectMapper();
    字节[]decodedValue=解码器.decode(值);
    返回objectMapper.readValue(decodedValue,this.resultClass);
    }捕获(IllegalArgumentException | JsonParseException e){
    String fieldName=parser.getParsingContext().getCurrentName();
    类wrapperClass=parser.getParsingContext().getCurrentValue().getClass();
    抛出新的InvalidFormatException(
    解析器,
    格式(““%s”的值不是base64编码的JSON”,字段名),
    价值
    包装类
    );
    }
    }
    }
    
    下面是一个映射类的示例。


    您的回答是正确的,您需要编写自己的反序列化程序,并使用jackson annotation
    @jsondeseserialize(using=foodeserializer.class)
    注册它。您能建议我如何编写一个自定义反序列化程序,它只解码base64编码的JSON,然后使用默认的反序列化程序吗?我已经找到了答案,但是我应该如何要求默认的反序列化程序将解码后的字符串作为对象其余部分的JSON处理?我注意到发出的请求是
    application/x-www-form-urlencoded
    格式,所以我不能在这里使用Jackson序列化程序。接受您的答案,因为它适用于问题中提出的Application/JSON。如果数据来自
    application/x-www-form-urlencoded
    ,您能提出一些建议吗?您能提供一个请求示例吗?键“varA”、“varB”在请求的顶层,或者它们被包装?是
    varA
    varB
    是顶层。类似这样的
    varB={base64encoded string here}&varA=“some string”
    。另外,我还提出了一个与此相关的单独问题。为了澄清,顶级对象是
    x-www-form-urlencoded
    ,其中
    varB
    包含base64编码的JSON,对吗?