Как сопоставить различные возможные типы полей JSON с атрибутом POJO? - PullRequest
1 голос
/ 20 октября 2019

У меня есть POJO, который используется для отображения значений, полученных из rabbitmq. Сообщения отправляются из сторонних сервисов, которые я не контролирую. Проблема состоит в том, что эти службы не отправляют определенные поля согласованным образом.

Например, в случае поля error это поле будет содержать информацию только тогда, когда сторонняя служба хочетотправить сообщение, чтобы сообщить, что есть ошибка. Некоторые службы могут отправлять свои JSON-сообщения в очередь следующим образом:

{
   id: 123,
   name: "PersonA",
   error: null
}

А затем существуют также службы, которые могут отправлять свои JSON-сообщения следующим образом:

{
   id: 123,
   name: "PersonA",
   error: []
}

также службы, которые могут просто пропустить это поле полностью:

{
   id: 123,
   name: "PersonA"
}

Конечно, если есть ошибка, это поле ошибки будет содержать поля внутри него:

{
   id: 123,
   name: "PersonA",
   error: {
      message: "Cannot find PersonA"
   }
}

Итак, естьвероятность того, что поле ошибки может быть null, undefined, array или object. Проблема в том, что я могу определить только один тип в своем POJO для поля error.

public class MyMessage {
    private int id;
    private MessageError error;
    private String name;

    @JsonCreator
    public MyMessage(
        @JsonProperty("id") int id,
        @JsonProperty("error") MessageError error,     // error is a MessageError object already but what is sent in could be null, undefined, an array or an object
        @JsonProperty("name") String name
    ) {
        this.id = id;
        this.error = error;
        this.name = name;
    }
}

public class MessageError {
    private String message;

    @JsonCreator
    public MessageError(
        @JsonProperty("message") String message
    ) {
        this.message = message;
    }
}

Я использую Spring с Джексоном. В этом случае, как я могу обработать и отобразить все возможные значения, которые могут быть присвоены полю error в сообщении, в POJO, когда оно десериализуется?

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Самый простой способ решить эту проблему - определить error поле как общий Object тип

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"id",
"name",
"error"
})
public class MyMessage {

@JsonProperty("id")
private int id;
@JsonProperty("name")
private String name;
@JsonProperty("error")
private Object error;

@JsonProperty("id")
public int getId() {
return id;
}

@JsonProperty("id")
public void setId(int id) {
this.id = id;
}

@JsonProperty("name")
public String getName() {
return name;
}

@JsonProperty("name")
public void setName(String name) {
this.name = name;
}

@JsonProperty("error")
public Object getError() {
return error;
}

@JsonProperty("error")
public void setError(Object error) {
this.error = error;
}

}

И затем вам необходимо сопоставить его с другим DTO:

// someplace where you will map it

MyMessage message = source.getMessageFromQueue();

if(message.getError() == null) {
  // do something
} else {
   Object error = message.getError();
   handleError(error);
}

private void handleError(Object error) {
   if(error instanceOf MessageError) {
       handleMessageError((MessageError) error) // handle as known MessageError object 
   } else if(error instanceOf String) {
       handleStringError((String) error) // handle as String, write in logs maybe
   } else if(error instanceOf List) {
       handleErrors((String) error) // handle as List errors
   } else {
       handleUndefinedError()
   }
}
0 голосов
/ 20 октября 2019

Если в данных json нет маркеров для определения их источника и, следовательно, его формы, я бы попытался установить тип поля ошибки для объекта, а если он не работает или не подходит, - для «json raw»как объяснено в ответах Как включить необработанный JSON в объект, используя Джексона? Таким образом, вы можете обработать поле ошибки соответствующим образом в соответствии с содержимым, которое вы обнаружите во время выполнения, исходя из ожидаемых вами подробностейвыше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...