我正在尝试使用请求正文构建REST post Web服务。使用昂首阔步和平针织物。
我为Body的一个属性定义了以下内容:(人为的例子)
petType:
description: Type of Pet
type: string
enum:
- CAT
- DOG
如果传入的请求不包含CAT或DOG,我想抛出一个http 400异常。
但是我永远不会有机会处理数据并抛出Http 400。相反,在Postman中,我获得了Http 500。堆栈跟踪 :
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type au.com.xyz.PetRequest$PetTypeEnum from String "DONKEY": value not one of declared Enum instance names: [CAT, DOG] at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@12b7aa1a; line: 4, column: 14] (through reference chain: au.com.xyz.PetPromoRequest["petType"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:74)
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1410)
at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:926)
at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeAltString(EnumDeserializer.java:189)
at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:126)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1583)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:964)
所以看起来甚至在我有机会验证Jackson / swagger / jersey正在做一些事情 - 我理想情况下不希望他们这样做!
有什么想法吗?
更新:基于娜塔莎的回答尝试了以下,它仍然无法正常工作
选项#1将@Priority注释添加到异常映射器:
@Provider
@Priority(1)
public class AppExceptionMapper implements ExceptionMapper<AppException> {
这没用。
选项#2在web.xml中添加以下内容:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.disableAutoDiscovery</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
我一直得到同样的例外:
引起:com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串“DONKEY”反序列化类型au.com.xyz.PetRequest $ PetTypeEnum的值:值不是声明的枚举实例名称之一:[CAT,DOG]在[来源:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@12b7aa1a; line:4,column:14](通过参考链:au.com.xyz.PetPromoRequest [“petType”])com的com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:74)。 F
您可以禁用Jersey的自动发现功能:resourceConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true);
其中resourceConfig的类型为org.glassfish.jersey.server.ServerConfig。
这是Jersey的异常处理程序的现有线程:Jersey unable to catch any Jackson Exception
更新:
用于解决Jackson错误:值不是声明的Enum实例名称之一
您可以使用@JsonCreater
抛出所需的异常:
public enum PET {
CAT("cat"),
DOG("dog");
private static MappingChange.Map<String, PET> FORMAT_MAP = Stream
.of(PET.values())
.collect(Collectors.toMap(s -> s.formatted, Function.identity()));
private final String formatted;
PET(String formatted) {
this.formatted = formatted;
}
@JsonCreator // This is the factory method and must be static
public static PET fromString(String string) {
// Throw desirable exception here
return Optional
.ofNullable(FORMAT_MAP.get(string))
.orElseThrow(() -> new IllegalArgumentException(string));
}
}