12 Replies Latest reply on Nov 18, 2005 8:10 AM by marius.oancea

    Entity beans with binary fields

    marius.oancea

      I have a requirement to create a Entity named Document. The bean has a field (persistent) that is of type Byte[].

      private Byte[] content;



      I will have to display such documents in my pages. I could do a Servlet called by an internal frame of the page i currently present but i dislike this solution. Any other solutions in seam ?

      In principle the document could be anythink (text + image + multimedia content) and has to be taken from database. I think I will only support mht and pdf (because simple html cannot embed images).



        • 1. Re: Entity beans with binary fields
          patrick_ibg

          What don't you like about the solution? The fact that it's a servlet outside of SEAM or that it's in a frame?

          You could produce your own output directly in any of the JSF phases (via interceptor or in the InvokeApplication phase)... you can get to the HttpResponse object via the FacesContext. It'll be similar logic to creating your own servlet, but at least you stay within the confines of SEAM/JSF.

          http://forum.java.sun.com/thread.jspa?threadID=570766&messageID=2828609

          • 2. Re: Entity beans with binary fields
            marius.oancea

            In fact what I have to do is to create a self containing document (containing text, formating and images) and I have to include it into my pages.

            I will have a displayDocument.xhtml that will present some metadata about the document and embeded, the document itself (i suppose in a iframe because i do not see another good option).

            The ideea with servlet i do not really like because there i will not see the ejb (at least not in a natural way).

            I understand what you mean with accesssing HttpResponse via FacesContext but can you detail a bit the ideea of "producing output directly in any of the JSF pahases....". Just point me to some documentation treating that. Thanx

            • 3. Re: Entity beans with binary fields
              patrick_ibg

              Check out the link from previous post on the sun forums. Essentially, from your "action" method (presumably a SEAM component), you grab the HttpResponse, set the content-type and other header info, and stream out the document data. Then you'll have to notify the JSF framework that you rendered the response yourself (so it doesn't do it for you).

              • 4. Re: Entity beans with binary fields
                marius.oancea

                Thanx very much. I missed the link in your first post. Thanx again.

                • 5. Re: Entity beans with binary fields
                  marius.oancea

                  Hi patrick, I understood what you stated and I did what you said:

                  In action I have:

                  public String viewContent() {
                  
                  disposition","attachment; filename=\"myHSSF.xls\"");
                  
                   HttpServletResponse response = (HttpServletResponse)facesContext.getExternalContext().getResponse();
                   response.setContentType("text/plain");
                   ServletOutputStream out;
                   try {
                   out = response.getOutputStream();
                   out.write("This is a test".getBytes());
                   out.flush();
                   } catch (Exception e) {
                   log.debug("Exception during writing content to iframe", e);
                   }
                   facesContext.responseComplete();
                   return null;
                   }




                  If i have in the xhtml the following code:

                  <h:commandLink value="download" action="#{learn.viewContent}" target="xxxx" />
                   <iframe name="xxxx">
                   </iframe>



                  then when I click on download i got the text in the iframe.

                  My problem is actually to get rid of pressing the download button. I want the content to be loaded into the iframe without user interaction.

                  I would like something like that:

                  <iframe src="...." />


                  But then the question is what to write instead of "...." to call the action method.

                  Maybe I could do the hack to make the download button invisible and to make a javascript to imitate pressing it but I do not really like this kind of hacks.

                  Any other ideas ?



                  • 6. Re: Entity beans with binary fields
                    lavoir
                    • 7. Re: Entity beans with binary fields
                      marius.oancea

                      I do not see any posibility with @Create. This is a method called by Seam when a component is created (not a GUI component but a SEAM component).

                      Either you know something very deap inside seam either you did not read my message .... not sure

                      • 8. Re: Entity beans with binary fields
                        patrick_ibg

                        I see...

                        I think the trick then is to format the iframe's src URI so that it looks like a JSF postback URI. I don't know enough about JSF to tell you how, but you can log the http request parameters to figure out what you'd need.

                        You'll probably have to use a different stateless component to render the iframe content, or use a stateful component in a conversation context for both the main page and iframe.

                        The first option is probably better in terms of resource usage. Additionally, you should lazy-fetch the byte[] data because you don't need it until the iframe makes it's http request. Some relevant info:

                        http://www.hibernate.org/41.html

                        • 9. Re: Entity beans with binary fields
                          marius.oancea

                          Solution was:

                          <div style="display: none;">
                           <h:commandLink id="dldCmdLink" value="download" action="#{courseTracker.viewItemContent}" target="downloadButton" />
                           </div>
                           <iframe id="downloadButton" name="downloadButton" width="100%" height="300">
                           </iframe>
                          
                           <script>
                           function addEvent(obj, evType, fn){
                           if (obj.addEventListener){
                           obj.addEventListener(evType, fn, false);
                           return true;
                           } else if (obj.attachEvent){
                           var r = obj.attachEvent("on"+evType, fn);
                           return r;
                           } else {
                           return false;
                           }
                           }
                          
                           function test() {
                           clear_linkDummyForm();
                           document.forms['linkDummyForm'].elements['linkDummyForm:_link_hidden_'].value='dldCmdLink';
                           document.forms['linkDummyForm'].target='downloadButton';
                           document.forms['linkDummyForm'].submit();
                           }
                          
                           addEvent(window, 'load', test);
                           </script>


                          • 10. Re: Entity beans with binary fields
                            gavin.king

                            That does not look like a very robust/portable solution.

                            I think you should probably be re-asking this question in a JSF-related forum.

                            • 11. Re: Entity beans with binary fields
                              marius.oancea

                              You are difinitelly right. Not very nice solution but works.

                              Any other solution is far more complicate to implement. As an example the myfaces forum answered me:
                              You might take a look at the implementation of
                              sandbox:graphicImageDynamic.
                              (org.apache.myfaces.custom.graphicimagedynamic in the sandbox)

                              The renderer sets up the URL (in your case, the stuff) with a custom request parameter, and
                              then the phase listener intercepts requests with that parameter and
                              renders out content based on that parameter value.

                              This seems similar to what you're trying to do, so maybe it'll provide
                              you with some ideas.

                              • 12. Re: Entity beans with binary fields
                                marius.oancea

                                btw. graphicImageDynamic is doing about the same (but more server side)