Leia a data como um array inteiro de json e mapeie com POJO como um inteiro
Estou recebendo json da api rest e quero armazenar os dados na lista do POJO. Abaixo está o código para o mesmo:
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;
}
Método que obtém a string da API restante:
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);
}
Abaixo está o meu 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"
} ]
}
Desde que eu não possa modificar o POJO existente (a menos e até que seja necessário), pois ele precisará de muitas modificações. Estou confuso sobre como acessar a data da matriz e mapeá-la para POJO, onde startDate tem tipo de dados inteiro.
Respostas
É possível definir um construtor anotado com @JsonCreator em POJO e, em seguida, analisar a lista de campos de data em json?
Algo parecido com isso.
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, 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();
}
}
}
Resultado:
2020922 2020924 OPEN
Se a atualização da classe POJO não for possível, há outra maneira alternativa de implementar um desserializador personalizado. Onde você pode implementar uma lógica de conversão semelhante.
Abordagem de desserialização personalizada
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\", \"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();
}
}
}
Resultado:
2020922 2020924 OPEN
NOTA: Lembre-se de implementar o tratamento de nulos corretamente.
Assumindo que você não deseja alterar o POJO, portanto, em vez da anotação @JsonDeserialize no nível da classe do bean, é necessário registrar este desserializador personalizado no código do cliente.