Gostaria de decodificar valores maiúsculos e minúsculos para um Java Enum em valores simples e em Array.
Eu tentei este pedaço de código:
public enum FooBarEnum {
FOO,
BAR
}
os seguintes POJOs para desserializar coisas:
public record Aaa(String something, FooBarEnum foobar)
public record Bbb(String something, List<FooBarEnum> foobarList)
Ao tentar obter o objeto via solicitação HTTP:
@GetExchange("/api/test1")
Aaa getAaa(@PathVariable int key);
Para isso, funciona, não importa se o servidor responde a um objeto com FOO, foo, BAR ou bar, funciona.
No entanto, tenho isto:
@GetExchange("/api/test2")
Bbb getBbb(@PathVariable int key);
Quando estiver em letras minúsculas, encontrarei esta exceção:
JSON decoding error: Cannot deserialize value of type `com.FooBarEnum` from String "foo": not one of the values accepted for Enum class: [FOO, BAR]
[...]
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.FooBarEnum` from String "foo": not one of the values accepted for Enum class: [FOO, BAR]
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 996] (through reference chain: com.Bbb["fooBarList"]-java.util.ArrayList[0])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67) ~[jackson-databind-2.18.3.jar:2.18.3]
Eu até tentei adicionar
@JsonFormat(with = {JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_VALUES})
mas sem sorte.
Existe uma maneira de lidar com o caso de ignorar para array também?
Este é um comportamento estranho. Por padrão, Jackson serializa e desserializa valores enum com o nome da constante correspondente. É por isso que
FOO
eBAR
são os únicos valores produzidos durante a serialização e os únicos aceitos na desserialização. Aqui está um exemplo para mostrar o comportamento. No seu caso, deve haver uma configuração ausente que faça o endpointgetAaa()
funcionar. Em vez disso,getBbb()
se comporta como esperado.Como você já mencionou, a anotação
@JsonFormat
junto com os recursosACCEPT_CASE_INSENSITIVE_PROPERTIES
eACCEPT_CASE_INSENSITIVE_VALUES
seria desserializada independentemente do caso. No entanto, ela deve anotar os campos enum. Não sei se talvez você tenha usado uma classe em vez de um registro e anotado outra coisa. Não está claro como você usou a anotação da postagem da pergunta. Aqui está uma demonstração com o comportamento desejado.Outra alternativa é definir um desserializador personalizado e registrá-lo com um módulo no
ObjectMapper
. Aqui está outra demonstração .