3 Replies Latest reply on Jul 7, 2008 4:36 PM by Jonas Erma

    Seam Remoting and Facelets

    Jonas Erma Newbie

      How do you guys use Seam Remoting and generate HTML fragments for rerenderable areas in a page?


      I'm planning a transition from Ajax4JSF to Seam Remoting without loosing the flexibility of generating HTML fragments using Facelets. Is it possible? I think there is no active faces context while a remote request is in progress, which means Facelet templates won't render. Is that correct? Can we trick the Facelet template into believing it is called in such a context?

        • 1. Re: Seam Remoting and Facelets
          ha kra Newbie

          i can offer you a class. it'll filter all calls to /remoting resources and store the HttpServletRequest, Response and ServletContext for your request. from within your seam remoting funtion you can then use RenderToString.servletContext.get() for example to get the current servlet context.
          if you got response request and servlet context, you can create your own facesContext and use that to render fragments into strings. my implementation doesnt work fully yet. but you can find a good sample if you search oreilly safari homepage for
          Returning a JSF View Response to a Non-JSF Request




          @Scope(APPLICATION)
          @Name("org.jboss.seam.remoting.remoting")
          @Install
          @BypassInterceptors
          public class RenderToString extends AbstractResource{
                 
                     @Override
                     public String getResourcePath()
                     {
                        return "/remoting";
                     }
                    
                     private AbstractResource original;
                     public static final ThreadLocal<HttpServletRequest> httpServletRequest = new ThreadLocal<HttpServletRequest>();
                     public static final ThreadLocal<HttpServletResponse> httpServletResponse = new ThreadLocal<HttpServletResponse>();
                     public static final ThreadLocal<ServletContext> servletContext = new ThreadLocal<ServletContext>();
                    
                     @Override
                     public void getResource(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
                             if(original == null) {
                                     try {
                                             original = (AbstractResource) Class.forName("org.jboss.seam.remoting.Remoting").newInstance();
                                  } catch (Exception e) {
                                          e.printStackTrace();
                                  }
                             }
                             original.setServletContext(getServletContext());
                             httpServletRequest.set(arg0);
                             httpServletResponse.set(arg1);
                             servletContext.set(getServletContext());
                             original.getResource(arg0, arg1);
                     }   
                 
          }

          • 2. Re: Seam Remoting and Facelets
            Dan Allen Master

            I cannot possibly understand why you would want to use Seam Remoting to render portions of your page. I just got done editing chapter 12 of Seam in Action where I explain that messing with the rendered page without JSF's knowledge is generally a bad idea. If you don't like Ajax4jsf, try ICEFaces which automatically calculates which portions of the page should be rendered.


            With that said, if you really do want to render something on the server, then you need to setup a FacesContext yourself, which is done inside of Seam for asynchronous method calls. Otherwise, you cannot render the Facelets templates.

            • 3. Re: Seam Remoting and Facelets
              Jonas Erma Newbie

              I actually achieved my goal some weeks after posting my first message. The following line works as expected in a @WebRemote method


              String fragment = renderer.render(viewId);


              It didn't work at the time of posting because of a bug in Seam. The bug has since been fixed in the trunk.



              I cannot possibly understand why you would want to use Seam Remoting to render portions of your page.

              Because I want to be in full control of the Ajax request/reply process. The Ajax frameworks you mentioned were buggy or at least not easily comprehensible to me to use them efficiently. Also, I didn't want to pay the performance penalty for some easy tasks.



              I just got done editing chapter 12 of Seam in Action where I explain that messing with the rendered page without JSF's knowledge is generally a bad idea.


              Would you mind sharing some of your arguments?


              Click HELP for text formatting instructions. Then edit this text and check the preview.