簡體   English   中英

如何有效傳入JSON並檢查缺少的屬性? [傑克遜,澤西]

[英]How to valid incoming JSON and check for missing properties? [Jackson,Jersey]

我正在使用Jackson 2.7.0。 最新的Jersey for JSON on REST API,用於處理與Hibernate 5+的數據庫通信。

如果其中有任何缺少的屬性,我不知道如何驗證傳入的JSON。 如果原始類型為null,則無法對其進行檢查。 但是我也想使用原始類型,因為性能受到了影響。 處理此類問題的最佳做法是什么?

當我收到如下的JSON時,一切正常:

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

但是當我收到JSON時:

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

然后將距離設置為默認值0

我的實體看起來像

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) {...

和REST方法:

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

試過的解決方案#1

我已經嘗試過,將所有值設置為默認值-1 ,然后檢查它是否小於0,但問題仍然是boolean值,我無法將其設置為“中性”值。

你通常如何處理JSON中缺少屬性的問題?

試過的解決方案#2

如您所見,我在構造函數中使用了@JsonProperty(value = "quantity", required = true) 這是Jackson 2.7.0。+的新功能,可以處理這類問題。 但我得到這個例外:

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

將此異常返回給用戶BEFORE JSON到達我的代碼。 所以我不能把它當成例外。 我有自定義響應與httpCode和errorMessage通知用戶有關它們。 問題是我不知道如何捕獲此異常並使用我的文本將其返回給我的自定義表單中的用戶。

尋找解決方案

我要么捕獲新傑克遜功能的例外,要么嘗試驗證JSON。 但是由於性能的原因,我不想使用類Integer而不是原始數據類型int。 如果有可能不為我在項目中的所有60多個類編寫自定義JSON反序列化器。

如果任何其他解決方案,然后傑克遜或澤西島支持這種類型的缺失屬性處理,請隨時評論。

TDLR - 如何檢查原始數據類型(int,double,boolean,...)的變量是否在傳入的JSON中,而無需為項目中的60多個類手動編寫反序列化器。 Java不允許使用null檢查這些類型。

建議#1

嘗試為JsonMappingException注冊ExceptionMapper,看看它是否覆蓋了Jersey已經注冊的那個。

我的代碼(仍然默認“缺少屬性...”異常 - 問題未解決):

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

}

解決這個問題的最簡單方法是在可選字段上使用對象計數器部分,它不應該影響您太多的性能,並允許您對字段進行空檢查。

public class Consumption {

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM