Сопоставление ответа JSON с абстрактным типом в JAVA rest Service

Я работаю с компанией электронной коммерции, и я интегрируюсь с 3 различными платежными шлюзами. Все они требуют обратного вызова для отправки статуса транзакции.

Я определил ресурс для хранения статуса транзакции

http://www.api.com/api/users/{userid}/order/{orderId}/payments/{paymentModeId}/paymentStatus

Я определил интерфейс под названием IPaymentStatusResponse и создал 3 реализации. На основе paymentModeId в пути uri будет выбрана соответствующая реализация для сохранения статуса транзакции.

например: URL-адрес обратного вызова для трех разных шлюзов будет выглядеть следующим образом: режим оплаты 1 - paytm, режим оплаты 2 - payu, режим оплаты 3- cc avenue.

http://www.api.com/api/users/300/order/501/payments/1/paymentStatus
http://www.api.com/api/users/300/order/501/payments/2/paymentStatus
http://www.api.com/api/users/300/order/501/payments/3/paymentStatus

Подпись метода

public void createPaymentStatus(
            @PathParam("paymentModeId") int paymentModeId,
            IPaymentStatusResponse response) throws MyAppException {
        paymentServiceImpl.createPaymentResponse(response, paymentModeId);
}

Это правильный подход?

Когда я отправлял HTTP-сообщение, я получаю следующую ошибку:

Can not construct instance of com.myapp.dto.payments.IPaymentStatusResponse, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@1ee3ab21; line: 1, column: 1]

Другой вариант, мне нужно будет определить разные конечные точки для всех разных шлюзов и сопоставить объект ответа.

ОБНОВЛЕНИЕ:

Хорошее объяснение можно найти здесь, http://programmerbruce.blogspot.in/2011/05/deserialize-json-with-jackson-into.html

Ему нужен элемент типа в ответе json, чтобы выбрать конкретный класс. Пример json с указанным типом и конфигурацией моего интерфейса. Это работает. Но не знаю, как с этим справиться, потому что ответ json не находится под моим контролем и исходит от поставщиков платежных шлюзов.

{
  "MID":"abc",
  "TXNID":"T123",
  "ORDERID":"100",
  "BANKTXNID":"B123",
  "TXNAMOUNT":"1",
  "CURRENCY":"INR",
  "STATUS":"TXN_SUCCESS",
  "RESPCODE":"01",
  "RESPMSG":"Txn Success",
  "TXNDATE":"2015-12-14 02:10:29.742447",
  "GATEWAYNAME":"ICICI",
  "BANKNAME":"ICICI",
  "PAYMENTMODE":"CC",
  "type":"PayTMPaymentResponse",  
  "CHECKSUMHASH":"ggg"
}

Интерфейс

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @Type(value = PayTMPaymentResponse.class, name = "PayTMPaymentResponse") })
public interface IPaymentStatusResponse {

}

Можно ли это реализовать с помощью какого-либо параметра запроса или пути?


person user5118993    schedule 14.12.2015    source источник


Ответы (1)


Spring / Jackson не может десериализоваться автоматически. Вам нужно будет предоставить собственный десериализатор для данного типа. Я думаю, что будет проще сделать одно POJO для общей информации и трех стратегий.

это должно помочь в случае, если вы используете Джексон. Я думаю, что в других библиотеках есть что-то подобное. http://wiki.fasterxml.com/JacksonPolymorphicDeserialization

person Vitalii Shevchuk    schedule 14.12.2015