2015-04-23 5 views
0

В приложении JEE, я создал перечисление с некоторыми строками пользовательских меток для GUI:Как я могу использовать разные Jackson JsonSerializers для одного и того же перечисления Java в разных местах?

public enum MyThing 
{ 
    THING1("Label 1"), 
    ... 
    THING5("Label 5"); 

    private String label; 

    private MyThing(String label) 
    { 
     this.label = label; 
    } 
    ... 
} 

объектов с атрибутами этого перечислимого типа доставляются через REST API. Значения атрибутов получить сериализации как идентификаторы строк, которым является то, что мне нужно:

класса с атрибутом перечислений:

public class MyBO 
{ 
    private MyThing thing; 
    ... 
} 

Класс обслуживания:

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
... 

@Path("/bos") 
public class MyBOsService 
{ 
    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public BO getBO() 
    { 
     BO bo = new BO(); 
     ... 
     return bo; 
    } 
} 

REST результат вызова:

{"thing":"THING1",...} 

Отлично! Теперь, однако, я хотел бы также поставить полный список идентификаторов и меток с помощью другого класса REST службы:

@Path("/masterdata") 
public class MasterDataService 
{ 
    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public MyThing[] allMyThings() 
    { 
     return MyThing.values(); 
    } 
} 

Желаемый результат REST вызова:

[{"THING1":"Label 1"},{"THING2":"Label 2"}, ...] 

Я создал обычай Джексон JsonSerializer сериализовать значение перечислений в виде пара ID-метке:

import org.codehaus.jackson.map.JsonSerializer; 
... 

public class MyThingSerializer extends JsonSerializer<MyThing> 
{ 
    @Override 
    public void serialize(MyThing myThing, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException 
    { 
    ... 
    } 
} 

Но теперь, я не могу найти разумное место для прикрепления этого JsonSerializer через @JsonSerialize аннотацию. Если я прикрепить его к перечислимому как

@JsonSerialize(using = MyThingSerializer.class) 
public enum MyThing{... 

все значениям перечислений получить сериализации как пары идентификатора-метка, которая является неправильной для всех вызовов REST, кроме одного.

Если я прикрепить его к методу предполагается доставить список пар ID-значение, ничего не происходит:

@Path("/masterdata") 
public class MasterDataService 
{ 
    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    @JsonSerialize(using = MyThingSerializer.class) 
    public MyThing[] allMyThings() 
    { 
     return MyThing.values(); 
    } 
} 

REST результат вызова:

["THING1","THING2",...] 

Я знаю, что я мог бы приложить «сериализатор идентификационных знаков» к самому перечислению, а затем присоединить другой сериализатор, который снова восстанавливает сериализацию по умолчанию во все другие вхождения перечисления, но есть ли более разумный способ достижения желаемых различных сериализаций в разных точках?

ответ

1

Вы можете указать индивидуальные сериализаторы для каждого объекта, используя @JsonSerialize(using=MySerializer.class).

В случае List с и массивов, вам нужно будет использовать:

@JsonSerialize(contentsUsing=MySerializer.class) 

поскольку using заменит сериалайзер, используемый для List или самого массива; для значений используется другой сериализатор.

+0

Это было полезно, поскольку я обратил внимание на то, что я использовал Jackson 1, в то время как я должен использовать Jackson 2, чтобы получить больше функциональности (например, элемент аннотации contentUsing). К сожалению, результат остается тем же: аннотирование метода allMyThings() с помощью '@JsonSerialize (contentsUsing = MyThingSerializer.класс) 'все еще не имеет никакого эффекта, результат вызова REST остается прежним. Я подозреваю, что вы просто не можете сериализовать значения enum на уровне метода. – Joe7

+0

Глядя на оригинальный пример, я подозреваю, что причина связана с тем, что вы аннотируете метод Resource, а не класс value. Обработка для них отличается тем, что происходит за пределами базы данных Jackson (Jackson получает значение, а не ресурсный метод, поэтому он буквально не может получить доступ к этим аннотациям). Теперь: это не значит, что он не может быть поддержан, но только то, что обрабатывает вызовы Джексона, обрабатывать аннотации. С JAX-RS поставщик Jackson JAX-RS по умолчанию (от https://github.com/FasterXML/jackson-jaxrs-providers) поддерживает некоторые аннотации, но ... – StaxMan

+0

.. но я не помню, если '@ JsonSerialize' /' @ JsonDeserialize' пока поддерживаются (в отличие от '@ JsonView', который, например). Обязательно используйте последнюю версию (2.5.3), если это возможно. В противном случае использование массива предотвращает некоторые из рабочих обходов (например: если у вас есть «Список», вы можете создать собственный подкласс, например «MyList», аннотировать этот тип!); если возможно, возможно, подумайте об использовании подтипа 'Collection' /' List', добавьте аннотацию к этому подклассу? – StaxMan

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

  • Нет связанных вопросов^_^