2014-12-12 2 views
0

Я использую Jackson для маршалирования вызовов json в веб-приложении, и я пытаюсь разработать метод, который будет принимать несколько разных объектов.Маршаллинг Map to Object с Jackson

Например:

У меня есть два класса структуры

{ 
    name:"Joe", 
    surname:"Bloggs" 
} 

Соответствует ява класса Person

{ 
    address1:"21 Main st", 
    city:"Georgetown", 
    zip:"12345" 
} 

соответствует адресу класса Java

Теперь я хочу сделать вызов, который может обрабатывать любой из этих классов таким образом:

{ 
     type:"Person", 
     data:{ 
     name:"Joe", 
     surname:"Bloggs" 
     } 
} 

Я могу создать вызов, маршалы поступивший запрос на карту или я могу создать два отдельных запросов, по одному для каждой структуры объекта и мобилизовывать их непосредственно в соответствующие классы.

Возможно ли использовать Джексон для маршализации вышеуказанного запроса на карту, а затем, прочитав часть карты - например. map.get («type») - используйте Jackson для маршалирования под-объекта - например. map.get ("data") - в соответствующий класс java без переустановки назад в json?

ответ

2

Полиморфизм Джексона можно использовать. Вот простой пример:

public class Polymorphism3Main { 

    public static void main(String []args) throws IOException { 
     ObjectMapper objectMapper = new ObjectMapper(); 

     String json = objectMapper.writeValueAsString(generatePerson()); 
     System.out.println("json = " + json); 
     System.out.println(objectMapper.readValue(json, Request.class)); 

     json = objectMapper.writeValueAsString(generateAddress()); 
     System.out.println("json = " + json); 
     System.out.println(objectMapper.readValue(json, Request.class)); 
    } 

    private static Person generatePerson() { 
     Person result = new Person(); 
     result.setName("name"); 
     result.setSurname("surname"); 
     return result; 
    } 

    private static Address generateAddress() { 
     Address address = new Address(); 
     address.setAddress1("address 1"); 
     address.setCity("city"); 
     address.setZip("324212"); 
     return address; 
    } 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) 
@JsonSubTypes({ 
     @JsonSubTypes.Type(value = Person.class, name = "person"), 
     @JsonSubTypes.Type(value = Address.class, name = "address") 
}) 
interface Request { 
} 

class Person implements Request { 
    private String name; 
    private String surname; 
} 

class Address implements Request { 
    private String address1; 
    private String city; 
    private String zip; 
} 

Этот код будет производить несколько иной JSON, но он по-прежнему Sutable:

{"person":{"name":"name","surname":"surname"}} 
{"address":{"address1":"address 1","city":"city","zip":"324212"}} 

Если вы хотите иметь точно такой же формат JSON, как вы писали - вы будете необходимо создать объект-оболочку.

В целом я бы рекомендовал создать два отдельных метода для обработки этих двух запросов по-разному. В этом случае код будет более чистым, и вам не нужно комбинировать интерфейс Person with Address via Request.

+0

Да, написание двух разных запросов - это подход, который я принимаю сейчас. Моя проблема заключается в том, что я в конечном итоге загружаю различные функции для обработки объектов, которые отличаются по структуре, но которые разделяют бизнес-логику так, как мне нужно их обрабатывать. Если вы сделаете это для двух объектов, это нормально, но если у вас есть десятки объектов, для которых вам нужно сделать, скажите четыре одинаковые операции для каждого (например, создать, обновить, удалить, список), вы получите 40 аналогичных методов , а не четыре. К сожалению, наличие общего наследования было бы слишком большим накладным в этой ситуации. – CuNimb

Смежные вопросы