boot将base64编码的JSON解码为POJO

boot将base64编码的JSON解码为POJO

本文介绍了使用jackson和spring-boot将base64编码的JSON解码为POJO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的请求

{
    "varA"  : "A",
    "varB" : "TCFNhbiBKb3NlMRgwFgYDVQQK"
}

其中key varB 是一个base64编码的JSON字符串。类似这样的事情:

where key varB is a base64 encoded JSON string. something like this:

{
    "nestedVarB1": "some value here",
    "nestedVarB2" : "some other value here"
}

我想把它转换成一些POJO像这个:

I want to convert it into some POJOs like this:

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

@Data
public class B {
    private String nestedVarB1;
    private String nestedVarB2;
}

我在堆栈溢出上经历了几个解决方案,如和,但我想将JSON直接转换为 MyRequest 类型的对象写一些杰克逊反序列化器。

I went through several solutions on stack overflow like this and this, but I want to convert the JSON directly into an object of type MyRequest maybe by writing some sort of Jackson deserializer.

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

How can I convert the JSON directly into MyRequest using Jackson and Spring Boot?

注意:


  1. POJOs MyRequest B 非常大, B 可以进一步嵌套,所以手动执行会很大任务。

  2. 我对来的请求没有任何控制权,它来自第三方来源。所以,不能改变请求的格式。

  1. POJOs MyRequest and B are very big and B could be further nested, so doing it manually would be a big task.
  2. I don't have any control over the request coming, it is coming from a third party source. So, can't change the format of the request.


推荐答案

我做了一些实验,这里是一个简单的杰克逊反序列化器,它应该适合你。

I've done some experiments and here is a simple Jackson Deserializer which should work for you.

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

Deserializer implements the ContextualDeserializer interface to get access to actual bean property (for example varB). It's necessary for detecting correct result type, because deserializer itself can be attached to a field of any type.

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;

import java.io.IOException;
import java.util.Base64;

public class Base64Deserializer extends JsonDeserializer<Object> implements ContextualDeserializer {

    private Class<?> resultClass;

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext context, BeanProperty property) throws JsonMappingException {
        this.resultClass = property.getType().getRawClass();
        return this;
    }

    @Override
    public Object deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
        String value = parser.getValueAsString();
        Base64.Decoder decoder = Base64.getDecoder();

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            byte[] decodedValue = decoder.decode(value);

            return objectMapper.readValue(decodedValue, this.resultClass);
        } catch (IllegalArgumentException | JsonParseException e) {
            String fieldName = parser.getParsingContext().getCurrentName();
            Class<?> wrapperClass = parser.getParsingContext().getCurrentValue().getClass();

            throw new InvalidFormatException(
                parser,
                String.format("Value for '%s' is not a base64 encoded JSON", fieldName),
                value,
                wrapperClass
            );
        }
    }
}

以下是映射示例类。

Here is an example of mapped class.

public class MyRequest {

    private String varA;

    @JsonDeserialize(using = Base64Deserializer.class)
    private B varB;

    public String getVarA() {
        return varA;
    }

    public void setVarA(String varA) {
        this.varA = varA;
    }

    public B getVarB() {
        return varB;
    }

    public void setVarB(B varB) {
        this.varB = varB;
    }
}

这篇关于使用jackson和spring-boot将base64编码的JSON解码为POJO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 23:38