В приложении 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",...]
Я знаю, что я мог бы приложить «сериализатор идентификационных знаков» к самому перечислению, а затем присоединить другой сериализатор, который снова восстанавливает сериализацию по умолчанию во все другие вхождения перечисления, но есть ли более разумный способ достижения желаемых различных сериализаций в разных точках?
Это было полезно, поскольку я обратил внимание на то, что я использовал Jackson 1, в то время как я должен использовать Jackson 2, чтобы получить больше функциональности (например, элемент аннотации contentUsing). К сожалению, результат остается тем же: аннотирование метода allMyThings() с помощью '@JsonSerialize (contentsUsing = MyThingSerializer.класс) 'все еще не имеет никакого эффекта, результат вызова REST остается прежним. Я подозреваю, что вы просто не можете сериализовать значения enum на уровне метода. – Joe7
Глядя на оригинальный пример, я подозреваю, что причина связана с тем, что вы аннотируете метод Resource, а не класс value. Обработка для них отличается тем, что происходит за пределами базы данных Jackson (Jackson получает значение, а не ресурсный метод, поэтому он буквально не может получить доступ к этим аннотациям). Теперь: это не значит, что он не может быть поддержан, но только то, что обрабатывает вызовы Джексона, обрабатывать аннотации. С JAX-RS поставщик Jackson JAX-RS по умолчанию (от https://github.com/FasterXML/jackson-jaxrs-providers) поддерживает некоторые аннотации, но ... – StaxMan
.. но я не помню, если '@ JsonSerialize' /' @ JsonDeserialize' пока поддерживаются (в отличие от '@ JsonView', который, например). Обязательно используйте последнюю версию (2.5.3), если это возможно. В противном случае использование массива предотвращает некоторые из рабочих обходов (например: если у вас есть «Список», вы можете создать собственный подкласс, например «MyList», аннотировать этот тип!); если возможно, возможно, подумайте об использовании подтипа 'Collection' /' List', добавьте аннотацию к этому подклассу? – StaxMan