英文:
How to fix JSON parse error in @requestbody and Enum value?
问题
我有两种方法:
- "JSON Body" 请求
- "Form param" 请求
第二种方法没问题,但是第一种方法有问题。
在这个方法中,当我发送一个枚举字段时,我得到以下错误:
JSON parse error: Cannot construct instance of ......service.dto.EuropeanLanguageEnumTypeDTO,问题:Unexpected value 'EN';nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException:Cannot construct instance of ......service.dto.EuropeanLanguageEnumTypeDTO,问题:Unexpected value 'EN'
at [Source: (PushbackInputStream); line: 6, column: 17] (through reference chain: ......service.dto.OrderCreateDTO["language"])
已解决 [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of ......service.dto.EuropeanLanguageEnumTypeDTO,问题:Unexpected value 'EN';nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException:Cannot construct instance of ......service.dto.EuropeanLanguageEnumTypeDTO,问题:Unexpected value 'EN'
at [Source: (PushbackInputStream); line: 6, column: 17] (through reference chain: ......service.dto.OrderCreateDTO["language"])]
EuropeanLanguageEnumTypeDTO.java:
public enum EuropeanLanguageEnumTypeDTO {
BG("bg"),
HR("hr"),
CS("cs"),
EN("en");
private String value;
EuropeanLanguageEnumTypeDTO(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static EuropeanLanguageEnumTypeDTO fromValue(String value) {
for (EuropeanLanguageEnumTypeDTO b : EuropeanLanguageEnumTypeDTO.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
此外,我还有另一个组件,用于转换枚举,但只适用于 'form' 请求:
@Component
public class EuropeanLanguageEnumConverter implements Converter<String, EuropeanLanguageEnumTypeDTO> {
@Override
public EuropeanLanguageEnumTypeDTO convert(String value) {
return EuropeanLanguageEnumTypeDTO.fromValue(value);
}
}
可以工作的 JSON 示例和不工作的示例:
成功:
{
"language": "en"
}
失败:
{
"language": "EN"
}
我需要能够处理大小写。我已经搜索了很多并尝试了一些不同的方法,比如 jackson.mapper.ACCEPT_CASE_INSENSITIVE_ENUMS: true
,但没有成功,请帮我解决这个问题。
附注:由于某些原因,我无法编辑 ENUM 类内部,因为它将与 openAPI 一起生成。
英文:
I've two methods:
- "JSON Body" request
- "Form param" request
@RequestMapping(value = "/orders.json", consumes = { "application/json" }, method = RequestMethod.POST)
@Override
public ResponseEntity<Void> createOrder(@Valid @RequestBody OrderCreateDTO orderCreateDTO) {
return doCreateOrder(orderCreateDTO);
}
@RequestMapping(value = "/orders.json", consumes = { "application/x-www-form-urlencoded" }, method = RequestMethod.POST)
public ResponseEntity<Void> createOrderForm(@Valid @ModelAttribute OrderCreateDTO orderCreateDTO) {
return doCreateOrder(orderCreateDTO);
}
The second method is fine, but there is an issue with the first.
In the method, when I sending an enum field, I got the following errors:
JSON parse error: Cannot construct instance of `......service.dto.EuropeanLanguageEnumTypeDTO`, problem: Unexpected value 'EN'; nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `......service.dto.EuropeanLanguageEnumTypeDTO`, problem: Unexpected value 'EN'\n at [Source: (PushbackInputStream); line: 6, column: 17] (through reference chain: ......service.dto.OrderCreateDTO[\"language\"])
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `.......service.dto.EuropeanLanguageEnumTypeDTO`, problem: Unexpected value 'EN'; nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `......service.dto.EuropeanLanguageEnumTypeDTO`, problem: Unexpected value 'EN'
at [Source: (PushbackInputStream); line: 6, column: 17] (through reference chain: ......service.dto.OrderCreateDTO["language"])]
EuropeanLanguageEnumTypeDTO.java:
public enum EuropeanLanguageEnumTypeDTO {
BG("bg"),
HR("hr"),
CS("cs"),
EN("en");
private String value;
EuropeanLanguageEnumTypeDTO(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static EuropeanLanguageEnumTypeDTO fromValue(String value) {
for (EuropeanLanguageEnumTypeDTO b : EuropeanLanguageEnumTypeDTO.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
Also, I've another component, to convert enum, but it just works only with 'form' request:
@Component
public class EuropeanLanguageEnumConverter implements Converter<String, EuropeanLanguageEnumTypeDTO> {
@Override
public EuropeanLanguageEnumTypeDTO convert(String value) {
return EuropeanLanguageEnumTypeDTO.fromValue(value);
}
}
Example of working JSON and not working:
success:
{
"language": "en"
}
fail:
{
"language": "EN"
}
I need to work with upper and lower case.
I search a lot and tried some different ways, such as jackson.mapper.ACCEPT_CASE_INSENSITIVE_ENUMS: true
, but didn't work, please help me with this issue.
P.s. for some reason I can't edit inside ENUM class, because it will generate with openAPI.
答案1
得分: 2
第二种解决方案:您使用的带有@JsonCreator的方法是可行的,但需要进行小的更改。在您的枚举中添加以下方法:
@JsonCreator
public static EuropeanLanguageEnumTypeDTO forValue(String value) {
return Stream.of(EuropeanLanguageEnumTypeDTO.values())
.filter(enumValue -> enumValue.name().equals(value.toUpperCase()))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
英文:
Second solution: the method which you use with @JsonCreator is ok but it needs small changes. Put to your enum the method below:
@JsonCreator
public static EuropeanLanguageEnumTypeDTO forValue(String value) {
return Stream.of(EuropeanLanguageEnumTypeDTO.values())
.filter(enumValue -> enumValue.name().equals(value.toUpperCase()))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
答案2
得分: -1
答案很简单,直接将枚举值放入你的DTO中,而不是使用字符串。
你不需要额外的映射器。
英文:
The answer is simple , try put in your DTO directly enum value instead of string.
You don't need additional mappers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论