从json中读取日期作为数组整数,并以POJO作为整数进行映射

问题描述

我从rest api获取json,我想将数据存储在POJO列表中。下面是相同的代码

   @Query("UPDATE Recipe SET recipeName = :recipe.recipeName WHERE recipeName = :oldName  ")
    suspend fun update(recipe: Recipe,oldName: String)

从rest api获取字符串方法

public List<myObject> mapper(){

    String myObjectData= restClient.getAllOriginal("myObject");

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNowN_PROPERTIES,false);
    objectMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY,true);

    
    List<CommitmentPojo> resultDto = null;

    try
    {

        Map<String,List<MyObject>> root = mapper.readValue(jsonString,new TypeReference<Map<String,List<MyObject>>>() {});
        List<MyObject> objects = root.get("myObject");
        
    }
    catch (JsonParseException e)
    {
        e.printstacktrace();
    }
    catch (JsonMappingException e) {
        e.printstacktrace();
    } catch (IOException e) {
        e.printstacktrace();
    }
    return resultDto;
}

下面是我的json:

public  String getAllOriginal(String resourcePath) {
       // Objects.requireNonNull(this.baseUri,"target cannot be null");
        return this.client
                .target("http://comtsrvc.ny.qa.flx.nimbus.gs.com:3802/v2/")
                .path(resourcePath)
                .request(MediaType.APPLICATION_JSON_TYPE)
                .cookie("mySSO",getCookie())
                .get()
                .readEntity(String.class);
    }

提供了我不能修改现有POJO(除非直到需要)的原因,因为它将需要大量修改。 我很困惑如何从数组访问日期并将其映射到startDate具有整数数据类型的POJO。

解决方法

是否可以在POJO中定义用@JsonCreator注释的构造函数,然后解析json中日期字段的列表?

与此类似。

Test.java

import java.util.List;

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

public class Test {
    private String state;
    private int startDate;
    private int endDate;

    @JsonCreator
    public Test(@JsonProperty("startDate") List<Integer> startDate,@JsonProperty("endDate") List<Integer> endDate) {
        StringBuilder stringBuilder = new StringBuilder();
        for (Integer value : startDate) {
            stringBuilder.append(value);
        }
        this.startDate = Integer.parseInt(stringBuilder.toString());
        stringBuilder.setLength(0);
        for (Integer value : endDate) {
            stringBuilder.append(value);
        }
        this.endDate = Integer.parseInt(stringBuilder.toString());
    }

    /**
     * @return the state
     */
    public String getState() {
        return state;
    }

    /**
     * @param state
     *            the state to set
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * @return the startDate
     */
    public int getStartDate() {
        return startDate;
    }

    /**
     * @param startDate
     *            the startDate to set
     */
    public void setStartDate(int startDate) {
        this.startDate = startDate;
    }

    /**
     * @return the endDate
     */
    public int getEndDate() {
        return endDate;
    }

    /**
     * @param endDate
     *            the endDate to set
     */
    public void setEndDate(int endDate) {
        this.endDate = endDate;
    }
}

Main.java

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        String json = "{\"state\" : \"OPEN\",\"startDate\" : [2020,9,22],\"endDate\" : [2020,24]}";

        ObjectMapper mapper = new ObjectMapper();
        try {
            Test test = mapper.readValue(json,Test.class);
            System.out.println(test.getStartDate() + "   " + test.getEndDate()
                    + "   " + test.getState());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

输出:

2020922   2020924   OPEN

如果无法更新POJO类,则可以使用另一种方法来实现自定义解串器。您可以在其中实现类似的转换逻辑。

自定义反序列化方法

CustomTest.java

public class CustomTest {
    private String state;
    private int startDate;
    private int endDate;

    /**
     * @return the state
     */
    public String getState() {
        return state;
    }

    /**
     * @param state
     *            the state to set
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * @return the startDate
     */
    public int getStartDate() {
        return startDate;
    }

    /**
     * @param startDate
     *            the startDate to set
     */
    public void setStartDate(int startDate) {
        this.startDate = startDate;
    }

    /**
     * @return the endDate
     */
    public int getEndDate() {
        return endDate;
    }

    /**
     * @param endDate
     *            the endDate to set
     */
    public void setEndDate(int endDate) {
        this.endDate = endDate;
    }
}

CustomTestDeserializer.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

public class CustomTestDeserializer extends StdDeserializer<CustomTest> {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public CustomTestDeserializer() {
        this(null);
    }

    protected CustomTestDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public CustomTest deserialize(JsonParser jp,DeserializationContext dCtxt)
            throws IOException,JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String state = node.get("state").asText();
        ObjectMapper mapper = new ObjectMapper();
        List<Integer> startDateValue = mapper.convertValue(
                node.get("startDate"),List.class);
        StringBuilder stringBuilder = new StringBuilder();
        for (Integer value : startDateValue) {
            stringBuilder.append(value);
        }
        int startDate = Integer.parseInt(stringBuilder.toString());

        List<Integer> endDateValue = mapper.convertValue(node.get("endDate"),List.class);
        stringBuilder.setLength(0);
        for (Integer value : endDateValue) {
            stringBuilder.append(value);
        }
        int endDate = Integer.parseInt(stringBuilder.toString());

        CustomTest customTest = new CustomTest();
        customTest.setEndDate(endDate);
        customTest.setStartDate(startDate);
        customTest.setState(state);
        return customTest;
    }
}

CustomTestClient.java

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class CustomTestClient {
    public static void main(String[] args) {
        String json = "{\"state\" : \"OPEN\",24]}";

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(CustomTest.class,new CustomTestDeserializer());
        mapper.registerModule(module);

        try {
            CustomTest customTest = mapper.readValue(json,CustomTest.class);
            System.out.println(customTest.getStartDate() + "   "
                    + customTest.getEndDate() + "   " + customTest.getState());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

输出:

2020922   2020924   OPEN

注意:请记住要正确实现空值处理。

假设您不想更改POJO,因此需要在客户端代码中注册此自定义反序列化器,而不是在bean类级别使用@JsonDeserialize注释。