Как сопоставить вложенное значение свойству с помощью аннотаций Джексона?
допустим, я делаю вызов API, который отвечает следующим JSON для продукта:
{
"id": 123,
"name": "The Best Product",
"brand": {
"id": 234,
"name": "ACME Products"
}
}
Я могу сопоставить идентификатор продукта и имя просто отлично, используя аннотации Джексона:
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;
}
}
а затем с помощью метода fromJson для создания продукта:
JsonNode apiResponse = api.getResponse();
Product product = Json.fromJson(apiResponse, Product.class);
но теперь я пытаюсь выяснить, как захватить фирменное наименование, которое является вложенным свойством. Я надеялся, что что-то вроде этого будет работать:
@JsonProperty("brand.name")
public String getBrandName() {
return brandName;
}
но конечно есть ли простой способ сделать то, что я хочу, используя аннотации?
фактический ответ JSON, который я пытаюсь разобрать, очень сложен, и я не хочу создавать целый новый класс для каждого подузла, хотя мне нужно только одно поле.
5 ответов:
вы можете достичь этого так:
String brandName; @JsonProperty("brand") private void unpackNameFromNestedObject(Map<String, String> brand) { brandName = brand.get("name"); }
вы можете использовать jsonpath-выражения для отображения вложенных свойств. Я не думаю, что есть какая-либо официальная поддержка (см. этой вопрос), но есть неофициальная реализация здесь:https://github.com/elasticpath/json-unmarshaller
вот как я справился с этой проблемой:
Brandкласс:package org.answer.entity; public class Brand { private Long id; private String name; public Brand() { } //accessors and mutators }
Productкласс:package org.answer.entity; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSetter; public class Product { private Long id; private String name; @JsonIgnore private Brand brand; private String brandName; public Product(){} @JsonGetter("brandName") protected String getBrandName() { if (brand != null) brandName = brand.getName(); return brandName; } @JsonSetter("brandName") protected void setBrandName(String brandName) { if (brandName != null) { brand = new Brand(); brand.setName(brandName); } this.brandName = brandName; } //other accessors and mutators }здесь
brandэкземпляр будет проигнорированоJacksonво времяserializationиdeserialization, так как он аннотируется с@JsonIgnore.
Jacksonбудет использовать метод с аннотацией@JsonGetterнаserializationобъекта java в . Итак,brandNameустановлен сbrand.getName().аналогично,
Jacksonбудет использовать метод с аннотацией@JsonSetterнаdeserializationнаJSONформатирование в объект java. В этом случае вам придется создать экземплярbrandобъект самостоятельно и установить егоnameсобственность отbrandName.можно использовать
@Transientсохранение аннотации сbrandName, если вы хотите, чтобы он был проигнорирован поставщиком сохраняемости.
чтобы сделать его простым ..Я написал код ...большинство из них не требует пояснений.
Main Methodpackage com.test; import java.io.IOException; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class LOGIC { public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException { ObjectMapper objectMapper = new ObjectMapper(); String DATA = "{\r\n" + " \"id\": 123,\r\n" + " \"name\": \"The Best Product\",\r\n" + " \"brand\": {\r\n" + " \"id\": 234,\r\n" + " \"name\": \"ACME Products\"\r\n" + " }\r\n" + "}"; ProductTest productTest = objectMapper.readValue(DATA, ProductTest.class); System.out.println(productTest.toString()); } }
Class ProductTestpackage com.test; import com.fasterxml.jackson.annotation.JsonProperty; public class ProductTest { private int productId; private String productName; private BrandName 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; } @JsonProperty("brand") public BrandName getBrandName() { return brandName; } public void setBrandName(BrandName brandName) { this.brandName = brandName; } @Override public String toString() { return "ProductTest [productId=" + productId + ", productName=" + productName + ", brandName=" + brandName + "]"; } }
Class BrandNamepackage com.test; public class BrandName { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "BrandName [id=" + id + ", name=" + name + "]"; } }
OUTPUTProductTest [productId=123, productName=The Best Product, brandName=BrandName [id=234, name=ACME Products]]
привет вот это полный рабочий код.
/ / JUNIT TEST CLASS
public class sof {
@Test public void test() { Brand b = new Brand(); b.id=1; b.name="RIZZE"; Product p = new Product(); p.brand=b; p.id=12; p.name="bigdata"; //mapper ObjectMapper o = new ObjectMapper(); o.registerSubtypes(Brand.class); o.registerSubtypes(Product.class); o.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); String json=null; try { json = o.writeValueAsString(p); assertTrue(json!=null); logger.info(json); Product p2; try { p2 = o.readValue(json, Product.class); assertTrue(p2!=null); assertTrue(p2.id== p.id); assertTrue(p2.name.compareTo(p.name)==0); assertTrue(p2.brand.id==p.brand.id); logger.info("SUCCESS"); } catch (IOException e) { e.printStackTrace(); fail(e.toString()); } } catch (JsonProcessingException e) { e.printStackTrace(); fail(e.toString()); } } } **// Product.class** public class Product { protected int id; protected String name; @JsonProperty("brand") //not necessary ... but written protected Brand brand; } **//Brand class** public class Brand { protected int id; protected String name; }//консоли.журнал junit testcase
2016-05-03 15:21:42 396 INFO {"id":12,"name":"bigdata","brand":{"id":1,"name":"RIZZE"}} / MReloadDB:40 2016-05-03 15:21:42 397 INFO SUCCESS / MReloadDB:49полная суть : https://gist.github.com/jeorfevre/7c94d4b36a809d4acf2f188f204a8058
Comments