【问题标题】:api validation for post body using jersey and swagger使用 jersey 和 swagger 对 post body 进行 api 验证
【发布时间】:2019-04-09 20:57:46
【问题描述】:

我正在尝试使用请求正文构建 REST 发布 Web 服务。 使用 swagger 和 jersey 相同。

我为 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 之前就在做一些事情——我最好不希望他们这样做!

有什么想法吗?

更新: 根据 Natasha 的回答,尝试了以下方法,但仍然无法正常工作

选项#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 , 狗] 在 [来源: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@12b7aa1a;行:4,列:14](通过引用链:au.com.xyz.PetPromoRequest["petType"]) 在 com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:74) 在com.f

【问题讨论】:

    标签: rest api swagger jersey-2.0


    【解决方案1】:

    您可以禁用 Jersey 的自动发现功能: resourceConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); 其中 resourceConfig 的类型为 org.glassfish.jersey.server.ServerConfig。

    这是 Jersey 异常处理程序的现有线程:Jersey unable to catch any Jackson Exception

    更新:

    为了解决 Jackson 错误:值不是声明的枚举实例名称之一

    您可以使用@JsonCreator 抛出所需的异常:

    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));
                    
        }
    }
    

    现有线程:Deserializing an enum with Jackson

    【讨论】:

    • 感谢 Natasha 根据您的反馈,我尝试了更多选项,但没有奏效。请查看我根据您的输入编辑的反馈
    • 嘿 Akila,我已经更新了答案。尝试相同的方法并告诉我们。
    猜你喜欢
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    相关资源
    最近更新 更多