Announcement Announcement Module
Collapse
No announcement yet.
Setting up media types dynamically Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Setting up media types dynamically

    Hi,
    The below is my scenario. I have been working on this for a quite a some time now without any luck
    I want to render the documents on the browser. I have done it before for pdf ( by configuring byte array message converter).But this is bit different. I won't be knowing the type of the document until i get it downloaded from the server. So either i have to set the media type dynamically or i should configure a collection of media types before hand. Here is what i have tried,
    Code:
    <int-http:inbound-gateway request-channel="Channel"
    		name="/Retrieve" supported-methods="GET" message-converters="byteArrayMessageConverter"/>
    
    	<int:channel id="Channel" />
    
    	<int:service-activator input-channel="Channel"
    		expression="@Service.fetchDocument(payload)" />
    and i have configured byte array message converter as follows,
    Code:
    <bean id="byteArrayMessageConverter"
    
    		class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
    
    		<property name="supportedMediaTypes">
    			<list>
    				
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="application" />
    					<constructor-arg value="pdf" />
    				</bean>
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="text" />
    					<constructor-arg value="plain" />
    				</bean>
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="text" />
    					<constructor-arg value="csv" />
    				</bean>
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="text" />
    					<constructor-arg value="xml" />
    				</bean>
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="application" />
    					<constructor-arg value="msword" />
    				</bean>
    				<bean class="org.springframework.http.MediaType">
    					<constructor-arg value="application" />
    					<constructor-arg value="vnd.ms-excel" />
    				</bean>
                                     </list>
    		</property>
    	</bean>
    But the above doesn't work as expected. Am i messed up anything?
    Any pointers on this?

    Thanks in Advance,
    Paary

  • #2
    Hello, Paary

    Can you explain what problem are you getting?
    set the media type dynamically
    You should set MessageHeader content-type manualy before you send reply into <http:inbound-gateway>
    It will be transalted into Response's HttpHeader before writing content into response.

    Hope it helps...

    Artem Bilan

    Comment


    • #3
      Artem,
      Paary and me work on the same team. To answer your question.

      This is the method signature corresponding to the ServiceActivator class which holds the business logic to get the document stream.

      public byte[] fetchDocument(LinkedMultiValueMap payload) throws Exception {

      My ServiceActivator expects the byte array and if the message-converters on the http-inbound gateway maps to a byteArrayMessageConverter that holds only one value (lets say application\pdf) and the byte array returns the same stream then all is fine.

      Now, we know we have mutiple MIME types to deal with. So we compiled them on the byteArrayMessageConverter ( as shown in the configuration Paary shared).

      How would SI know which MIME type to associate with the message-converters @ runtime? I think we need to return from the ServiceActivator an Object that can hold the byte stream as well as the MIME type indicator. Where we are struggling is which object to use and when we return the data 1) how to associate the byte stream with the anonymous reply channel that SI will configure under the hood and 2) how to map the MIME type to the appropriate byteArrayMessageConverter value from the list configured.

      Comment


      • #4
        You may want to look at this sample which demonstrates exactly what you need https://github.com/SpringSource/spri...multipart-http

        Comment


        • #5
          There are a couple of things you can do.

          1. If you want your service to remain as a POJO, do as you suggest and return an object containing the byte[] and MediaType; then use a header-enricher and transformer to set up the reply....

          Code:
          <int:chain input-channel="fromSA">
              <int:header-enricher header="contentType" expression="payload.contentType"/>
              <int:transformer expression="payload.byteArray"/>
          </int:chain>
          2. Return a Message<byte[]> from your service method and use
          Code:
               return MessageBuilder.withPayload(bytes).setHeader("contentType", ...).build();

          Comment


          • #6
            Well, I understand your task.

            So, let me make step back.
            1. HttpRequestHandlingEndpointSupport already has ByteArrayHttpMessageConverter
            2.
            Code:
            HttpMessageConverter#canWrite(Class<?> clazz, MediaType mediaType) 
            HttpMessageConverter#write(T t, MediaType contentType, HttpOutputMessage outputMessage)
            These methods are used for determine appropriate Converter and put into HttpHeaders some content-type with writing payload into response outputStream.
            3. For example. If you can determine content-type of your document in the fetchDocument just return Map<String, Object>
            One key contains your byte[], another - is determined content-type.
            4. And now it is simple:
            HTML Code:
            <chain input-channel="Channel">
                <service-activator  ref="Service" method="fetchDocument"/>
                <header-enricher> 
                    <header name="content-type" expression="payload[contentType]"/>
                </header-enricher>
                <transformer expression="payload[document]"/>
            <chain>
            Otherwise 'content-type' will be determined by request's 'accept-type' header.

            Comment


            • #7
              return MessageBuilder.withPayload(bytes).setHeader("conte ntType", ...).build();
              Don't do this in the <service-activator>: you are losing REPLY_CHANNEL Header for the return into gateway.
              Gary, sorry ;-)

              Comment


              • #8
                Artem that is incorrect.
                Code:
                return MessageBuilder.withPayload(bytes).setHeader("conte ntType", ...).build();
                is safe, since original headers (including REPLY_CHANNEL) wil still be copied in AbstractReplyProducingMessageHandler.createReplyMe ssage(..) method

                Comment


                • #9
                  is safe, since original headers (including REPLY_CHANNEL) wil still be copied
                  E-h-h... It is.
                  Haste makes waste.

                  my contention is about <transformer>

                  Comment


                  • #10
                    vendor specific documents not displayed properly

                    Thanks Oleg, Gary and Artem for your valuable inputs
                    Artem,
                    I tried the approach as pointed out by you.
                    I'm able to render pdfs, images etc on the browser with out any issues. But when comes to vendor specific (like WORD, EXCEL), we are not getting the document on the browser as expected.
                    Say, if it is a word document, i get many special characters along with text in the browser.
                    if its an excel, once i hit the end point, it tries to open it as a zipped file

                    Any pointers on this?

                    Thanks,
                    Paary

                    Comment


                    • #11
                      But when comes to vendor specific (like WORD, EXCEL)
                      Which 'Content-Type' response header are you seeing in the browser in this case?
                      Is it that, what are you setting on the server?

                      Maybe is it problem of your browser and it can't open Microsoft object directly?

                      Comment


                      • #12
                        The content type is application/msword for .doc. i checked for the content type. Its fine.
                        May be as pointed by you, it has something to do with my browser settings.
                        Let me check that first.
                        Thanks again Artem

                        Comment


                        • #13
                          content type is application/msword for .doc
                          H-m-m.
                          I think it is wrong.
                          Try this one:
                          HTML Code:
                          <mime-mapping>
                            <extension>xls</extension>
                            <mime-type>application/vnd.ms-excel</mime-type>
                          </mime-mapping>
                          <mime-mapping>
                            <extension>doc</extension>
                            <mime-type>application/vnd.ms-word</mime-type>
                          </mime-mapping>
                          <mime-mapping>
                            <extension>ppt</extension>
                            <mime-type>application/vnd.ms-powerpoint</mime-type>
                          </mime-mapping>
                          taken from jbossweb.deployer\web.xml

                          Comment


                          • #14
                            sure Artem. I will try as suggested by you

                            Comment


                            • #15
                              Artem, it ain't working. I still get the doc rendered in browser with many special characters and boxes. So i believe it could be related to the browser.

                              Comment

                              Working...
                              X