7 Replies Latest reply on Jan 5, 2006 12:24 AM by julien1

    Setting the response Content-type

    dunks80

      So in my portlet.xml I've set the conent type for a particular portlet with the following config...

      <portlet>
       <description>A portlet for creating and editing purchase orders</description>
       <display-name>Purchase Order Portlet</display-name>
       <portlet-name>PurchaseOrderPortlet</portlet-name>
       <portlet-class>org.apache.myfaces.portlet.MyFacesGenericPortlet</portlet-class>
       <init-param>
       <name>default-view</name>
       <value>/content/index.xhtml</value>
       </init-param>
       <supports>
       <mime-type>text/html</mime-type>
       </supports>
       <supports>
       <mime-type>text/xml</mime-type>
       </supports>
      
       <portlet-info>
       <title>Purchase Order Portlet</title>
       </portlet-info>
       <security-role-ref>
       <role-name>administrator</role-name>
       </security-role-ref>
       </portlet>
      


      When try to set the content type of the response writer to "text/xml" I get the following exception...
      14:14:13,122 ERROR [[/po]] Content type not accepted
      java.lang.IllegalArgumentException: Content type not accepted
       at org.jboss.portal.portlet.impl.RenderResponseImpl.setContentType(RenderResponseImpl.java:78)
      ...
      


      Do i have to specify the supported content type anywhere else?

        • 1. Re: Setting the response Content-type

          Did you try:

          <supports>
          <mime-type>bla</mime-type>
          <mime-type>bla</mime-type>
          <mime-type>bla</mime-type>
          <mime-type>bla</mime-type>
          </support>
          


          Wild guess.

          • 2. Re: Setting the response Content-type
            dunks80

            Actually I did try that initially but it yelled at me when I started the portal saying something about too many elements...so I figured that wasn't allowed...

            • 3. Re: Setting the response Content-type
              dunks80

              Could someone please explain how the ContentTypeInterceptor, ModesInterceptor and the supports section of the portlet.xml file work to set the content type of the response. Looking at the ContentTypeInterceptor it appears that the response is always going to be text/html no matter what is put in the supports section. I'm probably missing something though.

              • 4. Re: Setting the response Content-type

                the content type interceptor determines the content type that the browser requested / can handle. The portal takes this content type as the allowed content type for the current request. Portlets that want to set a particular content type need to first check if the current request supports that content type.
                Just think about it: if the browser makes a request and the expected content type is text/html, what is the portal supposed to do if one of the portlets returns text/xml ? Or in the reverse: if the request's content type is text/xml and now one of the portlets tries to set it's content type to text/html . What should the portal do? Wrap the fragment in a CDATA section, or ...?

                If you want to be able to write text/xml from a portlet, your entire request needs to be rendering text/xml content. This requested content type is, as you correctly stated above, determined by the ContentTypeInterceptor.

                • 5. Re: Setting the response Content-type
                  dunks80

                   

                  mholzner wrote:

                  the content type interceptor determines the content type that the browser requested / can handle


                  I guess I'm just not seeing how the ContentTypeInterceptor actually does what you said.

                  ...
                  try
                   {
                   // Set UTF-8 for parameter decoding
                   HttpServletRequest req = invocation.getRequest().getContext().getClientRequest();
                   req.setCharacterEncoding("UTF-8");
                   }
                   catch (UnsupportedEncodingException e)
                   {
                   throw new InvocationRuntimeException("Cannot set request encoding", e);
                   }
                  
                   // Configure the stream info
                   HTTPStreamInfo info = new HTTPStreamInfo(MediaType.HTML, "UTF-8");
                   ServerResponse resp = invocation.getResponse();
                   resp.setStreamInfo(info);
                  
                   // Continue invocation
                   invocation.invokeNext();
                  ...
                  


                  It seems to just set the allowed MediaType to HTML. So even if I make a request from the client with a content type of text/xml and I have a portlet which supports that content type and i try to set the content type of the response to text/xml in the portlet there is the check of the requested media type against the response media type (set by the ContentTypeInterceptor to always be HTML) at line 76 of org.jboss.portal.portlet.impl.RenderResponseImpl. text/xml is not a supported subtype of HTML (rightly so) and so the check fails and throws the IllegalArgumentException.



                  • 6. Re: Setting the response Content-type

                    ahem, I guess in theory it should ;)

                    You are right. It is hard coded for now. I wasn't aware of that.

                    Time for some community contributions :)

                    Since we're on this topic, does anyone have experince with CC/PP?
                    How would that fit into this discussion.
                    My current thinking is that this , or a more specific, interceptor would have to disect the info from the http headers and construct the correct content type, and additional data in the StreamInfo class. How would portlets/ layouts / themes take advantage of this information down the call stack? Anyone ?

                    • 7. Re: Setting the response Content-type

                      Yes it is, the reason are :

                      1. simplicity
                      2. people can change it by changing the interceptor anyway