super.t
super.t

Reputation: 2736

HttpRequestHandlingMessagingGateway JSON array payload

I can't get an HTTP inbound adapter to convert a JSON array to a list of objects of type SendgridTxEvent, it always ends up with ArrayList<LinkedHashMap> instead of List<SendgridTxEvent>. The config:

public HttpRequestHandlingMessagingGateway sendgridMessageAdapter(@Qualifier("sendgridWebhookEvents") MessageChannel channel) {
        HttpRequestHandlingMessagingGateway httpInboundChannelAdapter = new HttpRequestHandlingMessagingGateway(false);

        RequestMapping mapping = new RequestMapping();
        mapping.setMethods(HttpMethod.POST);
        mapping.setPathPatterns("/webhook/sendgrid");

        ParameterizedTypeReference<List<SendgridTxEvent>> ptr = new ParameterizedTypeReference<List<SendgridTxEvent>>() {
        };

        httpInboundChannelAdapter.setRequestMapping(mapping);
        httpInboundChannelAdapter.setRequestChannel(channel);
        httpInboundChannelAdapter.setRequestPayloadType(ResolvableType.forType(ptr));

        return httpInboundChannelAdapter;
    }

If I set the request payload type to httpInboundChannelAdapter.setRequestPayloadType(ResolvableType.forType(SendgridTxEvent.class)) and feed a JSON object to it (instead of an array), jackson deserializes SendgridTxEvent correctly, so the problem only occurs with an array input. Input examples can be found here.

How do I go about consuming JSON arrays in an HTTP inbound adapter?

SendgridTxEvent class:

@JsonIgnoreProperties(ignoreUnknown = true)
public class SendgridTxEvent {
    public enum Event {
        PROCESSED,
        DROPPED,
        DELIVERED,
        BOUNCE,
        DEFERRED,
        OPEN,
        CLICK,
        UNSUBSCRIBE,
        SPAMREPORT;

        @JsonCreator
        public static Event forValue(String value) {
            return Event.valueOf(value.toUpperCase());
        }
    }

    private String email;
    private Long timestamp;
    private Event event;

    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private List<String> category;
    private String sgEventId;
    private String sgMessageId;

//getters, setters

}

Upvotes: 1

Views: 300

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121272

I've raised an issue to fix this in the Framework: https://github.com/spring-projects/spring-integration/issues/2806

Meanwhile as a workaround I would suggest to expect a payload in the HttpRequestHandlingMessagingGateway as String or byte[], then use a POJO @Transformer downstream with direct conversion via ObjectMapper and already your expected <List<SendgridTxEvent> type.

Another simple option that you can expect just SendgridTxEvent[].class and than convert it into the list downstream.

Upvotes: 1

Related Questions