1

I am very new to Spring Integration and trying to figure out how to return a stream of data, but cannot find any examples. I found documentation around the ByteStreamWritingMessageHandler, but it seems kind of vague to me and doesn't provide an example of usage (other than bean definition). I'm assuming what I need to do is define a channel that uses the ByteStreamWritingMessageHandler and reference it in my inbound-gateway (via reply-channel), but I have some questions:

First, am I right? Can I use the default channel type? Do I need a channel adapter? Can I just return a ByteArrayOutputStream from my service method? What would the channel definition look like?

Any help would be greatly appreciated.

---------------UPDATE-----------

Our current endpoints are structured like this:

<int:channel id="httpReplyChannel"/>
<int:channel id="exampleService.exampleMethod"/>
<int-http:inbound-gateway path="/example"
                          supported-methods="POST"
                          request-channel="exampleService.exampleMethod"
                          request-payload-type="java.lang.Integer"
                          reply-channel="httpReplyChannel"
                          message-converters="jsonMessageConverter"
                          mapped-request-headers="*"/>
<int:service-activator input-channel="exampleService.exampleMethod"
                       ref="exampleService"
                       method="exampleMethod"/>

So we use two channels one for inbound and one for outbound and use the reply-channel attribute of the http:inbound-gateway to configure the outbound channel. I would like to follow the same pattern, but create a new outbound channel. My problem is that I'm not sure what type of channel would work best for returning a stream. The endpoint will return an a stream containing an image directly to the browser (which will make the request via the HTML img tag). So, I need my exampleMethod to return a stream (ByteArrayOutputStream) and I need to have access to dynamically set headers based on what type of image is being returned.

sevenstripe
  • 635
  • 1
  • 6
  • 12
  • I need to understand your use case in more detail. `MessageHandler`s such as that one are 'one-way' endoints (outbound). You can't just "hook one up" to an inbound gateway. To answer your question further, I need to know what kind of gateway you are talking about and more detail about what you are trying to do. There are many possibilities but I don't want to waste my (or your) time with speculation. – Gary Russell Jun 14 '13 at 06:29
  • Thanks Gary, I will update the original post with some more details. – sevenstripe Jun 17 '13 at 14:33

1 Answers1

0

If you are saying you want to receive a request via an http inbound adapter and somehow open a stream to pump multiple data out then, no that is not currently supported.

Spring Integration is primarily a messaging framework, not a streaming framework.

The Streaming adapters you refer to are for simple one-way integration.

All gateways are strictly request/response. There are certain adapters (such as tcp) where you can perform this kind of streaming (with collaborating inbound/outbound adapters), but there is not currently anything in the http space (although we are currently looking at a number of technologies that will enable such in the future).

EDIT: In response to the first comment below

That question/answer is not streaming the output, it's returning a byte[] in the ResponseEntity. If that's what you want to do, simply return a message with a byte[] payload (and appropriate content-type header).

If you really want your service to get a reference to the response outputstream, no you can't do that with the standard http gateway. However, you can use a simple servlet/controller and inject a <gateway/> to send a request to SI; the gateway's interface might be

public interface MyInterface {

    String foo(@Payload String request, @Header("stream") OutputStream stream);
}

with the service-activator having expression="@fooService.bar(payload, headers['stream'])".

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Essentially what I'm trying to do is referenced [here](http://stackoverflow.com/questions/5690228/spring-mvc-how-to-return-image-in-responsebody). However, I can't pass in HttpServletResponse as a parameter to the service, since it may not always be called via Http. Is there no way to access the outgoing byte stream? – sevenstripe Jun 18 '13 at 01:25
  • Thanks Gary, the byte array is the right approach for what I'm doing. One last question is how can I dynamically set the content-type header? The images will be of different types and I will need to check a field in the DB to know the mime-type. – sevenstripe Jun 18 '13 at 12:47
  • 1
    Just add it to the `content-type` header of the SI message and it will be mapped to the Http `Content-Type` header. If your service returns a `Message`, simply use `return MessageBuilder.withPayload(myBytes).setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build();` If you don't want to expose the SI infrastructure to your code, return a `Map` and use a `` and `` to do the necessary conversion. – Gary Russell Jun 18 '13 at 14:49
  • Thank you...the return type of Message instead of byte[] is what I was missing. – sevenstripe Jun 18 '13 at 16:02