2013-09-20 2 views
5

Скажем, у меня есть фасоль:Джексон - Изменение атрибута во время выполнения без аннотации

public class Msg { 
    private int code; 
    private Object data; 

    ... Getter/setters... 
} 

И преобразовать его в формат JSON или XML с такого рода тестовый код:

public String convert() { 
    Msg msg = new Msg(); 
    msg.setCode(42); 
    msg.setData("Are you suggesting coconuts migrate?"); 

    ObjectMapper mapper = new ObjectMapper(); 
    return mapper.writeValueAsString(msg); 
} 

Выход будет как-то так:

{"code":42,"data":"Are you suggesting coconuts migrate?"} 

Теперь, скажем, я хочу, чтобы заменить атрибут «данные» с некоторым динамическим именем:

public String convert(String name) { 
    Msg msg = new Msg(); 
    msg.setCode(42); 
    msg.setData("Are you suggesting coconuts migrate?"); 

    ObjectMapper mapper = new ObjectMapper(); 
    // ...DO SOMETHING WITH MAPPER ... 
    return mapper.writeValueAsString(msg); 
} 

Если я вызываю функцию обращенного ("тотализатор") Я woukld нравится иметь этот результат:

{"code":42,"toto":"Are you suggesting coconuts migrate?"} 

Если я вызываю функцию обращенного ("заводной") I woukld хотели бы иметь этот выход:

{"code":42,"groovy":"Are you suggesting coconuts migrate?"} 

конечно, я мог бы сделать строку, заменить после создания JSON, но если у вас есть ответ с ар Я возьму это.

Благодаря

+0

Преобразуйте объект в 'Map ' с вашими желаемыми ключами, а затем сериализуйте это? – millimoose

+0

Вы правы, это работает, и это то, что я делаю на данный момент, но мне было интересно, есть ли способ выполнения этого времени ... –

ответ

6

Вы можете использовать PropertyNamingStrategy класс для переопределения класса. См простую реализацию этого класса:

class ReplaceNamingStrategy extends PropertyNamingStrategy { 

    private static final long serialVersionUID = 1L; 

    private Map<String, String> replaceMap; 

    public ReplaceNamingStrategy(Map<String, String> replaceMap) { 
     this.replaceMap = replaceMap; 
    } 

    @Override 
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { 
     if (replaceMap.containsKey(defaultName)) { 
      return replaceMap.get(defaultName); 
     } 

     return super.nameForGetterMethod(config, method, defaultName); 
    } 
} 

Пример программы может выглядеть следующим образом:

import java.io.IOException; 
import java.util.Collections; 
import java.util.Map; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.PropertyNamingStrategy; 
import com.fasterxml.jackson.databind.cfg.MapperConfig; 
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; 

public class JacksonProgram { 

    public static void main(String[] args) throws IOException { 
     Msg msg = new Msg(); 
     msg.setCode(42); 
     msg.setData("Are you suggesting coconuts migrate?"); 

     System.out.println(convert(msg, "test")); 
     System.out.println(convert(msg, "toto")); 
     System.out.println(convert(msg, "groovy")); 
    } 

    public static String convert(Msg msg, String name) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.setPropertyNamingStrategy(new ReplaceNamingStrategy(Collections.singletonMap("data", name))); 
     return mapper.writeValueAsString(msg); 
    } 
} 

Над программа печатает:

{"code":42,"test":"Are you suggesting coconuts migrate?"} 
{"code":42,"toto":"Are you suggesting coconuts migrate?"} 
{"code":42,"groovy":"Are you suggesting coconuts migrate?"} 
+1

Thanx для этого, он отлично работает, и он по-прежнему настраивается для эволюций ... –

3

Одним из возможных вариантов было бы использовать так называемый «любой геттер ":

public class Msg { 
    public int code; 

    @JsonAnyGetter 
    public Map<String,Object> otherFields() { 
    Map<String,Object> extra = new HashMap<String,Object>(); 
    extra.put("data", findDataObject()); // or whatever mechanism you want 
    extra.put("name", "Some Name"); 
    return extra; 
    } 
} 

, чтобы вы могли возвращать произвольный набор динамических свойств.

Существует также соответствующий механизм «любой геттер» (@JsonAnyGetter), который вы можете использовать для принятия дополнительных свойств.

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