Mapa valor-chave de cada valor de um enum em Java

beegotsy:

Tarefa

Em um projeto back-end Java, eu tenho alguns (100+) enums externos que não posso editar e eu preciso para enviá-las para o nosso front-end. Eu queria enviá-las em um JSON-objeto como forma. Cada enum tem nome diferentes propriedades.

por exemplo, para a seguinte enumeração

public enum Colors {
  RED(1, "RED", "ff0000", Boolean.TRUE),
  GREEN(2, "GREEN", "00ff00", Boolean.FALSE),
  BLUE(3, "BLUE", "0000ff", Boolean.TRUE);

  private int code;
  private String label;
  private String hexCode;
  private boolean isAwesome;

  // ... getters and other methods
}

Eu quero saída

[
  {
    label: "RED"
    hexCode: "ff0000"
    isAwesome: true
  },
  {
    label: "GREEN"
    hexCode: "00ff00"
    isAwesome: false
  },
  ...
]

minha tentativa

Eu sou novo para Java, esta é a primeira vez que eu usei a reflexão e eu realmente não estudar nada antes de ir para isso. Provavelmente existem alguns grandes problemas com este código (como desempenho ou algum outro material estranho que eu não sei), mas ele compila e faz o trabalho. Eu não sei se isso é seguro, então eu perguntar se há alguns melhores maneiras de fazer isso.

private <T> List<HashMap<String, Object>> enumInserter(Class<T> clazz, List<String> properties) {
    return valuesToMap(clazz.getEnumConstants(), parserFactory(clazz, properties));
}

/**
* 
* @param <T>    type of the enum class
* @param values enumConstants of the enum
* @param parser a function that take a single enumValue of type <T> and returns
*               an property-value map
* @return the array of the property-value maps of each value
*/
private <T> List<HashMap<String, Object>> valuesToMap(T[] values, Function<T, HashMap<String, Object>> parser) {
  List<HashMap<String, Object>> enumValues = new ArrayList<>();
  for (T enumValue : values) {
    HashMap<String, Object> processedValue = parser.apply(enumValue);
    enumValues.add(processedValue);
  }
  return enumValues;
}

/**
* 
* @param <T>        the type of the enum class
* @param clazz      the enum class
* @param properties the properties to be added in the map
* @return a parser function that take a single enumValue of type <T> as input and
*         returns a property-value map of the given enumValue
*/
private <T> Function<T, HashMap<String, Object>> parserFactory(Class<T> clazz, List<String> properties) {
  return ((T enumValue) -> {
    HashMap<String, Object> map = new HashMap<>();

    properties.stream().forEach(propertyName -> {
      String methodName = getterFromProperty(propertyName);
      try {
        Method method = clazz.getMethod(methodName);
        Object methodResult = method.invoke(enumValue);
        map.put(propertyName, methodResult);
      } catch (Exception e) {
        // ... error logging
      }
    });

    return map;
  });
}

/**
* Return the "standard" property getter of a property. e.g. "example" will
* return "getExample"
* 
* @param property
* @return property getter method name
*/
private String getterFromProperty(String property) {
  return "get" + property.substring(0, 1).toUpperCase() + property.substring(1);
}
Alexandar Petrov:

A abordagem usual para isso é tanto através do uso de anotação @JsonFormat(shape = JsonFormat.Shape.OBJECT)ou através do uso de um serializer customizado.

Vamos dizer que você está fazendo referência a enumeração da classe A

class A {

   @JsonFormat(shape = JsonFormat.Shape.OBJECT)
   private Colors color;

}

isso fará com que a cor a ser serializado da maneira que quiser.

aproach alternativa seria registrar um serializador personalizado para o seu Enum isso, você pode fazer o seguinte caminho:

public class ColorSerializer extends StdSerializer {

    public ColorSerializer() {
        super(Color.class);
    }

    public ColorSerializer(Class t) {
        super(t);
    }

    public void serialize(Color color, JsonGenerator generator,
      SerializerProvider provider) 
      throws IOException, JsonProcessingException {
        generator.writeStartObject();
        generator.writeFieldName("code");
        generator.writeString(color.getCode());
        generator.writeFieldName("hexCode");
        generator.writeString(color.getHexcode());
        generator.writeFieldName("isAwsome");
        generator.writeNumber(color.isAwsome());
        generator.writeEndObject();
    }
}

Desde suas enums são externos você pode sempre colocá-los em embalagens que são internos ao seu projeto e desta forma controlar o seu processo de serialização.

Se você quiser serializar-los usando a mesma estratégia que você pode colocar seu código reflexo no serializer. Desta forma, você terá um único serializer genérico, em vez de escrever para cada enum.

Isto é como você pode registrar o serializador personalizado:

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addSerializer(Color.class, new ColorSerializer ());
mapper.registerModule(module);

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=192328&siteId=1
Recomendado
Clasificación