从JSON中读取日期作为整数数组,并与POJO中的整数进行映射。

huangapple go评论63阅读模式
英文:

Read date as an array integer from json and map with POJO as an integer

问题

以下是翻译好的内容:

从 REST API 获取 JSON 数据并希望将数据存储在 POJO普通 Java 对象的列表中以下是相应的代码

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<MyObject> 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;
}

从 REST API 获取字符串的方法

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);
    }

以下是我的 JSON 数据

{
  
  "myObject" : [ {
    "key" : {
      "srcSys" : "REPO_1",
      "srcSysRef" : "20200909_1911_1"
    },
    "productData" : {
      "id" : null,
      "number" : null,
      "isn" : null,
      "productId" : null,
      "productAdditionalData" : {
        "assetClassTree" : "UNCLASSIFIED",
        "description" : "UNCLASSIFIED",
        "productTypeData" : {
          "productType" : "UNCLASSIFIED",
          "productGroup" : "UNCLASSIFIED"
        }
      }
    },
    "state" : "OPEN",
    "type" : "01"
  }, {
    "key" : {
      "srcSys" : "REPO_2",
      "srcSysRef" : "20200403_3892_1"
    },
    "productData" : {
      "id" : "1",
      "number" : "11",
      "isn" : "null",
      "productId" : 1234,
      "productAdditionalData" : {
        "assetClassTree" : "xyz",
        "description" : "abc",
        "productTypeData" : {
          "productType" : "UNCLASSIFIED",
          "productGroup" : "UNCLASSIFIED"
        }
      }
    },
    "state" : "OPEN",
    "startDate" : [2020, 9, 22],
    "endDate" : [2020, 9, 24],
    "tradAcctType" : "01"
  } ]
}

鉴于我不能修改现有的 POJO除非必要),因为这需要很多修改我对如何从数组中访问日期并将其映射到具有整数数据类型的 POJO其中 startDate 具有整数数据类型感到困惑
英文:

I'm getting json from rest api and I want to store the data in list of POJO. Below is the codefor the same:

public List&lt;myObject&gt; mapper(){
String myObjectData= restClient.getAllOriginal(&quot;myObject&quot;);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
List&lt;CommitmentPojo&gt; resultDto = null;
try
{
Map&lt;String, List&lt;MyObject&gt;&gt; root = mapper.readValue(jsonString, new TypeReference&lt;Map&lt;String, List&lt;MyObject&gt;&gt;&gt;() {});
List&lt;MyObject&gt; objects = root.get(&quot;myObject&quot;);
}
catch (JsonParseException e)
{
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return resultDto;
}

Method which gets the string from rest api:

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

Below is my json:

{
&quot;myObject&quot; : [ {
&quot;key&quot; : {
&quot;srcSys&quot; : &quot;REPO_1&quot;,
&quot;srcSysRef&quot; : &quot;20200909_1911_1&quot;
},
&quot;productData&quot; : {
&quot;id&quot; : null,
&quot;number&quot; : null,
&quot;isn&quot; : null,
&quot;productId&quot; : null,
&quot;productAdditionalData&quot; : {
&quot;assetClassTree&quot; : &quot;UNCLASSIFIED&quot;,
&quot;description&quot; : &quot;UNCLASSIFIED&quot;,
&quot;productTypeData&quot; : {
&quot;productType&quot; : &quot;UNCLASSIFIED&quot;,
&quot;productGroup&quot; : &quot;UNCLASSIFIED&quot;
}
}
},
&quot;state&quot; : &quot;OPEN&quot;,
&quot;type&quot; : &quot;01&quot;
}, {
&quot;key&quot; : {
&quot;srcSys&quot; : &quot;REPO_2&quot;,
&quot;srcSysRef&quot; : &quot;20200403_3892_1&quot;
},
&quot;productData&quot; : {
&quot;id&quot; : &quot;1&quot;,
&quot;number&quot; : &quot;11&quot;,
&quot;isn&quot; : &quot;null&quot;,
&quot;productId&quot; : 1234,
&quot;productAdditionalData&quot; : {
&quot;assetClassTree&quot; : &quot;xyz&quot;,
&quot;description&quot; : &quot;abc&quot;,
&quot;productTypeData&quot; : {
&quot;productType&quot; : &quot;UNCLASSIFIED&quot;,
&quot;productGroup&quot; : &quot;UNCLASSIFIED&quot;
}
}
},
&quot;state&quot; : &quot;OPEN&quot;,
&quot;startDate&quot; : [2020, 9, 22],
&quot;endDate&quot; : [2020, 9, 24],
&quot;tradAcctType&quot; : &quot;01&quot;
} ]
}

Provided that I cannot modify the existing POJO(unless and until required) as it will need a lot of modifications.
I'm confused how to access date from the array and map it to POJO where startDate has integer data type.

答案1

得分: 2

以下是翻译好的部分:

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());
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public int getStartDate() {
        return startDate;
    }

    public void setStartDate(int startDate) {
        this.startDate = startDate;
    }

    public int getEndDate() {
        return endDate;
    }

    public void setEndDate(int endDate) {
        this.endDate = endDate;
    }
}
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, 9, 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();
        }
    }
}
public class CustomTest {
    private String state;
    private int startDate;
    private int endDate;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public int getStartDate() {
        return startDate;
    }

    public void setStartDate(int startDate) {
        this.startDate = startDate;
    }

    public int getEndDate() {
        return endDate;
    }

    public void setEndDate(int endDate) {
        this.endDate = endDate;
    }
}
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;
    }
}
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\", \"startDate\" : [2020, 9, 22], \"endDate\" : [2020, 9, 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();
        }
    }
}

注意:请确保适当实现空值处理。假设您不想更改 POJO,因此,而不是在 bean 类级别使用 @JsonDeserialize 注解,需要在客户端代码中注册此自定义反序列化程序。

英文:

Is it possible for you to define a constructor annotated with @JsonCreator in POJO and then parse the List<Integer> for date fields in json?

Something similar to this.

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(&quot;startDate&quot;) List&lt;Integer&gt; startDate,
@JsonProperty(&quot;endDate&quot;) List&lt;Integer&gt; 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 = &quot;{\&quot;state\&quot; : \&quot;OPEN\&quot;, \&quot;startDate\&quot; : [2020, 9, 22], \&quot;endDate\&quot; : [2020, 9, 24]}&quot;;
ObjectMapper mapper = new ObjectMapper();
try {
Test test = mapper.readValue(json, Test.class);
System.out.println(test.getStartDate() + &quot;   &quot; + test.getEndDate()
+ &quot;   &quot; + test.getState());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

Output:

2020922   2020924   OPEN

If POJO class update is not possible then there is another alternative way to implement a custom deserializer. Where you can implement similar conversion logic.

Custom Deserialization approach

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&lt;CustomTest&gt; {
/**
* 
*/
private static final long serialVersionUID = 1L;
public CustomTestDeserializer() {
this(null);
}
protected CustomTestDeserializer(Class&lt;?&gt; vc) {
super(vc);
}
@Override
public CustomTest deserialize(JsonParser jp, DeserializationContext dCtxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
String state = node.get(&quot;state&quot;).asText();
ObjectMapper mapper = new ObjectMapper();
List&lt;Integer&gt; startDateValue = mapper.convertValue(
node.get(&quot;startDate&quot;), List.class);
StringBuilder stringBuilder = new StringBuilder();
for (Integer value : startDateValue) {
stringBuilder.append(value);
}
int startDate = Integer.parseInt(stringBuilder.toString());
List&lt;Integer&gt; endDateValue = mapper.convertValue(node.get(&quot;endDate&quot;),
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 = &quot;{\&quot;state\&quot; : \&quot;OPEN\&quot;, \&quot;startDate\&quot; : [2020, 9, 22], \&quot;endDate\&quot; : [2020, 9, 24]}&quot;;
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() + &quot;   &quot;
+ customTest.getEndDate() + &quot;   &quot; + customTest.getState());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

Output:

2020922   2020924   OPEN

NOTE: Please remember to implement null handling properly.

Assuming you don't want to change the POJO hence instead of @JsonDeserialize annotation at bean class level, need to register this custom deserializer at client code.

huangapple
  • 本文由 发表于 2020年9月22日 15:10:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64004700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定