如何有效传入JSON并检查缺少的属性? [杰克逊,泽西] [英] How to valid incoming JSON and check for missing properties? [Jackson,Jersey]

查看:538
本文介绍了如何有效传入JSON并检查缺少的属性? [杰克逊,泽西]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jackson 2.7.0。和最新的Jersey for JSON on REST API来处理与Hibernate 5 +的数据库通信。



我不知道如何验证传入的JSON是否有任何缺少的属性。如果原始类型为null,则不可能执行对原始类型的检查。但我也想使用原始类型,因为性能受到影响。
处理这类问题的最佳做法是什么?



当我收到下面的JSON时,一切正常:

  {vehicle:{id:1},distance:1000,quantity:2000} 

但是当我收到JSON时:

  {车辆:{id:1},quantity:2000} 

默认值 0



我的实体看起来像

  public class Consumption {

private int id;
私人双倍数量;
私人双倍距离;

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
公共消费(
@JsonProperty(value =quantity,required = true)double数量,
@JsonProperty(value =distance,required = true)double distance,
@JsonProperty(value =vehicle,required = false)车辆){...


和REST方法:

  @POST 
@Path(/ setConsumption /)
public Response setConsumption(@Valid Consumption consum){...



尝试过的解决方案#1



我已经尝试过将所有值设置为默认值 -1 然后检查它是否小于0,但问题依然存在于布尔值值中,我无法将其设置为中性值。 p>

您如何处理JSON中缺少属性的问题?



试过解决方案#2



正如你可以看到我已经使用 @JsonProperty(value =q uantity,required = true)在构造函数中。这是Jackson 2.7.0。+的新功能,可以处理这类问题。但我得到这个例外:

 
处缺少必要的创建者属性'distance'(索引1)[Source:org .glassfish.jersey.message.internal.ReaderInterceptorExecutor $ @ UnCloseableInputStream 1b72cb6; line:1,column:181]

这个异常返回给用户BEFORE JSON到达我的代码。所以我不能把它当作例外。我有自定义的httpCode和errorMessage响应通知用户。问题是我不知道如何捕捉这个异常,并用我的文本将其返回给用户。



寻找解决方案



我要么捕获新杰克逊功能的异常,要么尝试验证JSON。但我不想使用类Integer而不是原始数据类型int,因为性能。
如果有可能不为我在项目中的所有60个以上的类编写定制JSON解串器。



如果有其他解决方案,那么Jackson或Jersey支持这种类型



TDLR - 如何检查原始数据类型的变量(int,double,boolean) ,...)是否在传入JSON中,而无需为项目中的60多个类中的每个类手动写入反序列化程序。 Java不允许使用 null 来检查这些类型。



建议#1



尝试为JsonMappingException注册一个ExceptionMapper并查看它是否覆盖Jersey已经注册的那个。



我的代码(仍然获取默认值)Missing property ...异常 - 问题没有解决):

$ $ $ $ $ $ $ $ $ $公共类JacksonNoPropertyMapper实现了ExceptionMapper< JsonMappingException> {
@Override
public ResponseResponse(JsonMappingException e){

return Response.status(999).entity(OVERRIDE TEST).type(MediaType.APPLICATION_JSON)。建立();
}

}

解决方案

最简单的方法是使用可选的字段上的对象计数器部分,它不应该影响您太多性能,并且允许您进行空值检查

 公共类消费{

private int id;
私人双倍数量;
私人双倍距离;

public boolean isDistanceSet(){
return distance!= null;
}


I'm using Jackson 2.7.0. and latest Jersey for JSON on REST API that handles DB communication with Hibernate 5+.

I don't know how to verify incoming JSON if there are any missing properties in it. It is impossible to perform checking on primitive type if they are null. But also i would like to use primitive types because of performance hit. What is best practice to handle such problem?

When I receive JSON like below, everything is ok:

{"vehicle":{"id":1},"distance":1000,"quantity":2000} 

But when i receive JSON like:

{"vehicle":{"id":1},"quantity":2000}

then distance is set to default value 0.

My entity look like

public class Consumption{

private int id;
private double quantity;
private double distance;

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public Consumption(
        @JsonProperty(value = "quantity", required = true)double quantity, 
        @JsonProperty(value = "distance", required = true)double distance,
        @JsonProperty(value = "vehicle", required = false)Vehicle vehicle) {...

And REST method:

@POST
@Path("/setConsumption/")
public Response setConsumption(@Valid Consumption consum){...

Tried solution #1

I have already tried, to set all values to default value of -1 and then check if it is less then 0, but problem remains with boolean values, where i can not set it to the "neutral" value.

How do you usually handle such problem with missing property in JSON?

Tried solution #2

As you can see i have used @JsonProperty(value = "quantity", required = true) in constructor. This is new feature for Jackson 2.7.0.+, that handles this type of problem. But i get this exception:

Missing required creator property 'distance' (index 1) at 
[Source:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@1b72cb6; line: 1, column: 181]

This exception is returned to user BEFORE JSON reaches my code. So i can not catch it as exception. I have custom responses with httpCode and errorMessage to inform user about them. Problem is that i don't know how to catch this exception and return it to user in my custom form with my text.

Searching for solution

I have either to catch exception of new Jackson feature or try to validate JSON. But i would not like to use class Integer instead of primitive data type int, because of performance. If it is possible not to write custom JSON deserializer for all 60+ classes i have in project.

If any other solution then Jackson or Jersey supports this types of handling of missing properties, feel free to comment.

TDLR - how to check if variable of primitive data type (int, double, boolean,...) was in incoming JSON or not, without manually writting deserializers for each of 60+ classes in project. Java does not allow to check those types with null.

Suggestion #1

Trying to register an ExceptionMapper for JsonMappingException and see if it overrides the one already registered by Jersey.

My code (still getting default "Missing property ..." exception - problem not solved):

@Provider
public class JacksonNoPropertyMapper implements ExceptionMapper<JsonMappingException> {
    @Override
    public Response toResponse(JsonMappingException e) {

    return Response.status(999).entity("OVERRIDE TEST").type(MediaType.APPLICATION_JSON).build();
}

}

解决方案

The easiest way for you to approach this would be to use the Object counter parts on fields that are optional, it shouldn't affect you too much performance wise, and would allow you to null check the fields.

public class Consumption {

private int id;
private double quantity;
private Double distance;

public boolean isDistanceSet() {
    return distance != null;
}

这篇关于如何有效传入JSON并检查缺少的属性? [杰克逊,泽西]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆