2017-01-25 10 views
0

Я использую fasterxml в 2.6.4 и получить следующий JSON с помощью внешнего сервиса, по которым я не имею никакого влияния на данном выходе:Deserialize квартира JSON в комплекс POJO

{ 
    "name": "dunnosName", 
    "widthValue": 46.1, 
    "heightValue": 56.1, 
    "depthValue": 66.1, 
    "unit": "mm" 
} 

и хочу отобразить его на следующие POJOs:

public class Dunno { 
    private String name; 
    private ValueWithUnit width; 
    private ValueWithUnit height; 
    private ValueWithUnit depth; 
} 

public class ValueWithUnit { 
    private Float value; 
    private String unit; 
} 

Мое освобожденное отображение должно выглядеть примерно так:

name -> Dunno.name 

widthValue -> Dunno.width.value 

heightValue -> Dunno.height.value 

depthValue -> Dunno.depth.value 

unit -> Dunno.width.unit 

unit -> Dunno.height.unit 

unit -> Dunno.depth.unit 

ли возможно ли реализовать ожидаемое сопоставление с помощью quickxml? И если это так, какие quickxml аннотации или классы мне нужно реализовать для реализации этого сопоставления?

+0

Просто взглянув на e docs, не совсем уверен, что это возможно (возможно, я не выглядел тщательно). Возможно, вам потребуется проксировать ответ и преобразовать его таким образом, чтобы получить что-то, что автоматически анализируется, например, преобразование каждого «значения», чтобы содержать значение и единицу. – Brendan

ответ

1

Не требуется переходный TempDunno. Вам нужен Custom Deserializer. Это пример учебника, в котором вы бы его использовали. Добавьте следующую аннотацию к Dunno класса:

@JsonDeserialize(using = DunnoDeserializer.class) 

и здесь, и с проверкой ввода, а также: метод

@SuppressWarnings("serial") 
public class DunnoDeserializer extends StdDeserializer<Dunno> 
{ 
    public DunnoDeserializer() 
    { 
     this(null); 
    } 

    public DunnoDeserializer(Class<?> vc) 
    { 
     super(vc); 
    } 

    @Override 
    public Dunno deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException 
    { 
     Dunno dunno = new Dunno(); 
     // first parse the input into a map, which is more convenient to work with 
     @SuppressWarnings("unchecked") 
     Map<String, Object> values = jp.getCodec().readValue(jp, Map.class); 
     dunno.name = values.containsKey("name") ? values.get("name").toString() : "empty"; 
     String unit = values.containsKey("unit") ? values.get("unit").toString() : "default-units"; 
     if (values.containsKey("widthValue")) { 
      dunno.width = new ValueWithUnit(); 
      dunno.width.value = ((Number)values.get("widthValue")).floatValue(); 
      dunno.width.unit = unit; 
     } 
     if (values.containsKey("heightValue")) { 
      dunno.height = new ValueWithUnit(); 
      dunno.height.value = ((Number)values.get("heightValue")).floatValue(); 
      dunno.height.unit = unit; 
     } 
     if (values.containsKey("depthValue")) { 
      dunno.depth = new ValueWithUnit(); 
      dunno.depth.value = ((Number)values.get("depthValue")).floatValue(); 
      dunno.depth.unit = unit; 
     } 
     System.out.println(values); 
     values.values().forEach(v -> System.out.println(v.getClass())); 
     return dunno; 
    } 
} 

тест:

public static void main(String[] args) 
{ 
    String jsonString = "{ \"name\": \"dunnosName\"," + "\"widthValue\": 46.1," + "\"heightValue\": 56.1," 
      + "\"depthValue\": 66.1," + "\"unit\": \"mm\"}"; 

    ObjectMapper mapper = new ObjectMapper(); 
    try { 
     Dunno d = (Dunno)mapper.readValue(jsonString, Dunno.class); 
     System.out.format("%s: %.2f(%s) %.2f(%s) %.2f(%s)", 
       d.name, d.width.value, d.width.unit, d.height.value, d.height.unit, d.depth.value, d.depth.unit); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

который дает ожидаемый результат:

dunnosName: 46.10(mm) 56.10(mm) 66.10(mm) 
+0

Идея хорошая, но предлагаемое решение не будет работать точно с частными полями, поэтому вам нужно использовать сеттеры – maloney

+0

Вы понимаете, что мы обсуждаем сообщение от 10 месяцев назад, правильно? во всяком случае, ** НЕТ ** решение будет работать с частными полями. здесь не проблема. предполагается, что получатели и сеттеры предоставляются. –

+0

Кроме того, «предложенное» решение было принято, поэтому я думаю, что он работает для OP –

-1
public class Dunno { 
    private String name; 
    private ValueWithUnit width; 
    private ValueWithUnit height; 
    private ValueWithUnit depth; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public ValueWithUnit getWidth() { 
     return width; 
    } 

    public void setWidth(ValueWithUnit width) { 
     this.width = width; 
    } 

    public ValueWithUnit getHeight() { 
     return height; 
    } 

    public void setHeight(ValueWithUnit height) { 
     this.height = height; 
    } 

    public ValueWithUnit getDepth() { 
     return depth; 
    } 

    public void setDepth(ValueWithUnit depth) { 
     this.depth = depth; 
    } 

    @Override 
    public String toString() { 
     return "Dunno{" + 
       "name='" + name + '\'' + 
       ", width=" + width + 
       ", height=" + height + 
       ", depth=" + depth + 
       '}'; 
    } 
} 

public class ValueWithUnit { 
    private Float value; 
    private String unit; 

    public ValueWithUnit(Float value, String unit) { 
     this.value = value; 
     this.unit = unit; 
    } 

    public Float getValue() { 
     return value; 
    } 

    public void setValue(Float value) { 
     this.value = value; 
    } 

    public String getUnit() { 
     return unit; 
    } 

    public void setUnit(String unit) { 
     this.unit = unit; 
    } 

    @Override 
    public String toString() { 
     return "ValueWithUnit{" + 
       "value=" + value + 
       ", unit='" + unit + '\'' + 
       '}'; 
    } 
} 

public class TempDunno { 
    private String name; 
    private Float widthValue; 
    private Float heightValue; 
    private Float depthValue; 
    private String unit; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Float getWidthValue() { 
     return widthValue; 
    } 

    public void setWidthValue(Float widthValue) { 
     this.widthValue = widthValue; 
    } 

    public Float getHeightValue() { 
     return heightValue; 
    } 

    public void setHeightValue(Float heightValue) { 
     this.heightValue = heightValue; 
    } 

    public Float getDepthValue() { 
     return depthValue; 
    } 

    public void setDepthValue(Float depthValue) { 
     this.depthValue = depthValue; 
    } 

    public String getUnit() { 
     return unit; 
    } 

    public void setUnit(String unit) { 
     this.unit = unit; 
    } 

    @Override 
    public String toString() { 
     return "TempDunno{" + 
       "name='" + name + '\'' + 
       ", widthValue=" + widthValue + 
       ", heightValue=" + heightValue + 
       ", depthValue=" + depthValue + 
       ", unit='" + unit + '\'' + 
       '}'; 
    } 
} 

public class Main { 

    public static void main(String[] args) throws IOException { 
     String json = "{\n" + 
       "  \"name\": \"dunnosName\",\n" + 
       "  \"widthValue\": 46.1,\n" + 
       "  \"heightValue\": 56.1,\n" + 
       "  \"depthValue\": 66.1,\n" + 
       "  \"unit\": \"mm\"\n" + 
       "}"; 

     System.out.println(getDunno(json)); 
    } 

    private static Dunno getDunno(String json) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     TempDunno tmp = mapper.readValue(json, TempDunno.class); 
     Dunno dunno = new Dunno(); 
     dunno.setName(tmp.getName()); 
     dunno.setHeight(new ValueWithUnit(tmp.getHeightValue(), tmp.getUnit())); 
     dunno.setWidth(new ValueWithUnit(tmp.getWidthValue(), tmp.getUnit())); 
     dunno.setDepth(new ValueWithUnit(tmp.getDepthValue(), tmp.getUnit())); 
     return dunno; 
    } 
}