【问题标题】:Jersey ignores unrecognized values in POST request bodyJersey 忽略 POST 请求正文中无法识别的值
【发布时间】:2018-01-31 16:53:58
【问题描述】:

目前,当输入 json 对象作为 POST 请求的主体时,Jersey 将忽略它无法识别的任何键/值对。

例子:

public class TestObject{
    private String value1;
    private Integer value2;

    // appropriate getters and setters
}

JSON 对象:

{
"value1":"test",
"value2":1,
"value3":"wrong"
}

在上述情况下,Jersey 将接受两个预期值并创建 TestObject 忽略“value3”输入。

如果无法识别 JSON 对象中的任何内容,是否有办法强制 Jersey 抛出异常而不是忽略该值?

编辑:

我的控制器看起来像这样:

@POST
@Consumes("application/json")
public Response handleTestObject(TestObject testObject){
//method execution here
}

所以我依靠 Jersey 将 json 输入转换为 TestObject

【问题讨论】:

  • 与其在 POST 正文中发送“错误”,不如尝试发送不同的状态码。例如,如果“错误”表示未填写某个值,则可以发送 400(错误请求)。
  • 那个 value3 是用户输入的一部分,不是我的回应
  • 你用什么将 Json 转换为对象?
  • stackoverflow.com/questions/31094305/… 。我觉得泽西岛会使用 Jackson/gson 进行转换。接受一个字符串并在转换为对象之前检查所有键。如果无效返回 400 。上面的链接将帮助您检查密钥
  • 在尝试上述方法之前。尝试使用 Jackson 或 gson 将 json 转换为对象 urself。我很确定它应该抛出异常

标签: java json rest jersey-2.0 unmarshalling


【解决方案1】:

当你使用jackson进行转换时,如果传入未知参数,它实际上应该默认抛出异常。我用杰克逊 2.26 试过这个:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.26</version>
</dependency>

它在没有任何进一步配置的情况下抛出了以下异常:

Unrecognized field "value3" (class de.jan.model.TestObject), not marked as ignorable (one known property: "test"])
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2ff055a5; line: 1, column: 25] (through reference chain: de.jan.model.TestObject["value3"])%

因此,如果您不受其他任何限制,您可能只是切换到 jackson 进行转换。

如果您已经在使用 jackson 但仍未收到此异常,则您(或您正在使用的某个库)可能在某处禁用了此行为。要将其恢复,您可以将以下注释添加到您的课程TestObject:

 @JsonIgnoreProperties(ignoreUnknown = false)

这将导致杰克逊在反序列化此特定类的实例时为其他字段抛出异常。

要为所有对象配置此行为,您需要创建一个自定义 ObjectMapper 解析器,如下所示:

@Provider
@Produces("application/json")
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperResolver() {
        mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}  

并在您的ResourceConfig 中注册该课程。

如果您使用的是 gson,您可能无能为力。支持未知属性处理程序存在一个未解决的问题,但到目前为止还没有发布。您可以在他们的issue tracker

中找到有关此的更多信息,包括手动检查其他字段的代码

【讨论】:

  • 谢谢!这很棒!我唯一的问题是我想捕捉错误并将我自己的消息发送回客户端。我有一个实现 ExceptionMapper 的 Provider 并且它没有捕获 Jackson 异常。你有什么建议吗?
  • 我想你可以在这里找到答案stackoverflow.com/questions/5833147/…
猜你喜欢
  • 1970-01-01
  • 2019-12-18
  • 2023-01-05
  • 2014-09-30
  • 2019-07-14
  • 2019-07-12
  • 2016-05-22
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多