简体   繁体   中英

Mapping JSON response to an abstract type in JAVA rest Service

I am working with an ecommerce company and I am integrating with 3 different payment gateways. All of them require a callbackurl to post back the transaction status.

I have defined a resource to store the status of the transaction

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

I have defined an interface called IPaymentStatusResponse and have created 3 implementations. Based on the paymentModeId in the uri path, appropriate implementation will be picked up to persist the transaction status.

eg: callback url for three different gatewyas will look like this payment mode 1 - paytm, payment mode 2 - payu ,payment mode 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

Method signature

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

Is this the correct way to approach this?

When I did a HTTP post I get the following error:

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]

Other option , I ll have to define different end points for all the different gateways and map the response object.

UPDATE:

A good explanation can be found here http://programmerbruce.blogspot.in/2011/05/deserialize-json-with-jackson-into.html

It needs a type element in the response json to pick the concrete class. Sample json with type mentioned and configuration of my interface. This works. But not sure how to handle this because the response json is not under my control and it comes from the payment gateway providers

{
  "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"
}

Interface

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

}

Can this be implemented with some query or path parameter ?

Spring/Jackson is not able to deserialize automatically. You'll have to provide custom deserializer for a given type. I think it should be easier to do one POJO for shared information and 3 strategies.

it should help in case if you're using jackson. I think other libs have something similar to that. http://wiki.fasterxml.com/JacksonPolymorphicDeserialization

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM