Digamos que estou fazendo uma chamada para uma API que responde com o seguinte JSON para um produto:
{
"id": 123,
"name": "The Best Product",
"brand": {
"id": 234,
"name": "ACME Products"
}
}
Consigo mapear a id e o nome do produto perfeitamente usando as anotações de Jackson:
public class ProductTest {
private int productId;
private String productName, brandName;
@JsonProperty("id")
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
@JsonProperty("name")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
}
E então usando o método fromJson para criar o produto:
JsonNode apiResponse = api.getResponse();
Product product = Json.fromJson(apiResponse, Product.class);
Mas agora estou tentando descobrir como obter o nome da marca, que é uma propriedade aninhada. Eu esperava que algo assim funcionasse:
@JsonProperty("brand.name")
public String getBrandName() {
return brandName;
}
Mas é claro que não. Existe uma maneira fácil de realizar o que desejo usando anotações?
A resposta JSON real que estou tentando analisar é muito complexa e não quero ter que criar uma nova classe inteira para cada subnó, embora precise apenas de um único campo.
Respostas:
Você pode conseguir isso assim:
fonte
this.abbreviation = ((Map<String, Object>)portalCharacteristics.get("icon")).get("ticker").toString();
Foi assim que resolvi esse problema:
Brand
classe:Product
classe:Aqui, a
brand
instância será ignorada porJackson
duranteserialization
edeserialization
, uma vez que é anotada com@JsonIgnore
.Jackson
usará o método anotado com@JsonGetter
forserialization
do objeto java noJSON
formato. Então, obrandName
está definido combrand.getName()
.Da mesma forma,
Jackson
usará o método anotado com@JsonSetter
fordeserialization
deJSON
format no objeto java. Nesse cenário, você mesmo terá que instanciar obrand
objeto e definir suaname
propriedade a partir debrandName
.Você pode usar
@Transient
a anotação de persistência combrandName
, se quiser que ela seja ignorada pelo provedor de persistência.fonte
Você pode usar expressões JsonPath para mapear propriedades aninhadas. Não acho que haja suporte oficial (veja este problema), mas há uma implementação não oficial aqui: https://github.com/elasticpath/json-unmarshaller
fonte
O melhor é usar métodos setter:
JSON:
O método setter para lat ou lng será semelhante a:
se você precisar ler ambos (como faria normalmente), use um método personalizado
fonte
Para tornar mais simples ... eu escrevi o código ... a maior parte dele é autoexplicativo.
Main Method
Class ProductTest
Class BrandName
OUTPUT
fonte
Olá, aqui está o código de trabalho completo.
// AULA DE TESTE DE JUNIT
public class sof {
//Console.log do caso de teste junit
Síntese completa: https://gist.github.com/jeorfevre/7c94d4b36a809d4acf2f188f204a8058
fonte