Announcement Announcement Module
Collapse
No announcement yet.
how to configure spring MVC - view resolver - for facelets Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • how to configure spring MVC - view resolver - for facelets

    Hello
    How do I setup ViewResolver for Facelets?
    I thought i could use InternalResourceView, but it seems it doesn't work

    Code:
    	<bean id="viewResolver"
    		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="cache" value="false" />
    		<property name="viewClass"
    			value="org.springframework.web.servlet.view.InternalResourceView" />
    		<property name="prefix" value="/WEB-INF/" />
    		<property name="suffix" value=".jsp" />
    	</bean>
    (.jsp is used for better eclipse support)

    the error is
    Code:
    The requested resource (/jsf1/WEB-INF/servlet/view) is not available

  • #2
    I'm not sure without seeing more detail, but I suspect that it is the FaceletViewHandler configuration that is in error, not the Spring ViewResolver. The FaceletViewHandler tries to replace the suffix on the end of your view name (after the last ".") with the default suffix name provided in web.xml, e.g.

    Code:
    	<context-param>
    		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    		<param-value>.xhtml</param-value>
    	</context-param>
    You might need to set this to .jsp as well, or maybe some more steps are needed in your case.

    Facelets is great and it works really well straight out of the box, if you follow the published examples. If you stray off the true path (and try and do anything real), it tends to get a bit more difficult. If I have one criticism of Facelets so far it is this.

    Comment


    • #3
      Has anyone gotten this to work?

      Hello All,
      Has anyone gotten Spring MVC to work with facelets?

      I love Spring MVC and a decision has been made by management, the rest of my team, and our designers to use facelets. We're trying to port an application from Seam to Spring MVC/WebFlow.

      I can get MVC working with JSF following the documentation, booking-faces integrates facelets and SWF, and booking-mvc uses MVC simultaneously with SWF, but no JSF/facelets + MVC + SWF.

      Does anyone have any configuration they could share?

      Thanks in advance,
      Steven
      Harvard Children's Hospital Informatics Program

      Comment


      • #4
        reply on how to configure spring MVC

        I'm not sure if this applies to Web Flow, but I do know that with Spring MVC, you have an option of having your controller implement the LastModified interface, which allows Spring to send the browser the "Last-Modified" HTTP header.

        Servlets typically don't set this HTTP header value, causing browsers to request a new copy of the files each time, however, if the "Last-Modified" header is set, browsers know not to retrieve the contents of a URL if it hasn't been modified since the page was last retrieved.

        I suspect your Web Flow "controller" (pardon my abuse of terminology, I'm not familiar with Web Flow) is setting the "Last-Modified" header, while your regular Facelets page is not.

        For what it's worth, I think setting Last-Modified is generally a good idea, unless your page is dynamic.

        Comment


        • #5
          RE: how to configure spring MVC - view resolver - for facelets

          FaceletViewResolver = Spring MVC + Facelets

          Step 1 - Include the following class in your project:

          package javax.faces.mvc.view;

          imports ...

          public class FaceletView extends AbstractUrlBasedView {

          private Lifecycle facesLifecycle;

          @Override
          public void afterPropertiesSet() throws Exception {
          super.afterPropertiesSet();
          facesLifecycle = createFacesLifecycle();
          }

          @Override
          protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response)
          throws Exception {

          FacesContext facesContext = createFacesContext(request, response);

          populateRequestMap(facesContext, model);

          FaceletView.notifyBeforeListeners(PhaseId.RESTORE_ VIEW, facesLifecycle, facesContext);

          ViewHandler viewHandler = facesContext.getApplication().getViewHandler();

          viewHandler.initView(facesContext);

          UIViewRoot viewRoot = viewHandler.createView(facesContext, getUrl());
          Assert.notNull(viewRoot, "A JSF view could not be created for " + getUrl());
          viewRoot.setLocale(RequestContextUtils.getLocale(r equest));
          viewRoot.setTransient(true);

          facesContext.setViewRoot(viewRoot);

          FaceletView.notifyAfterListeners(PhaseId.RESTORE_V IEW, facesLifecycle, facesContext);

          facesContext.setViewRoot(viewRoot);
          facesContext.renderResponse();
          try {
          FaceletView.notifyBeforeListeners(PhaseId.RENDER_R ESPONSE, facesLifecycle, facesContext);
          logger.debug("Asking view handler to render view");
          facesContext.getApplication().getViewHandler().ren derView(facesContext, viewRoot);
          FaceletView.notifyAfterListeners(PhaseId.RENDER_RE SPONSE, facesLifecycle, facesContext);
          } catch (IOException e) {
          throw new FacesException("An I/O error occurred during view rendering", e);
          } finally {
          logger.debug("View rendering complete");
          facesContext.responseComplete();
          facesContext.release();
          }
          }

          private void populateRequestMap(FacesContext facesContext, Map model) {
          Iterator i = model.keySet().iterator();
          while (i.hasNext()) {
          String key = i.next().toString();
          facesContext.getExternalContext().getRequestMap(). put(key, model.get(key));
          }
          }

          private FacesContext createFacesContext(HttpServletRequest request, HttpServletResponse response) {
          FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTE XT_FACTORY);
          return facesContextFactory.getFacesContext(getServletCont ext(), request, response, facesLifecycle);
          }

          private Lifecycle createFacesLifecycle() {
          LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_F ACTORY);
          return lifecycleFactory.getLifecycle(LifecycleFactory.DEF AULT_LIFECYCLE);
          }

          public static void notifyAfterListeners(PhaseId phaseId, Lifecycle lifecycle, FacesContext context) {
          PhaseEvent afterPhaseEvent = new PhaseEvent(context, phaseId, lifecycle);
          for (int i = 0; i < lifecycle.getPhaseListeners().length; i++) {
          PhaseListener listener = lifecycle.getPhaseListeners()[i];
          if (listener.getPhaseId() == phaseId || listener.getPhaseId() == PhaseId.ANY_PHASE) {
          listener.afterPhase(afterPhaseEvent);
          }
          }
          }

          public static void notifyBeforeListeners(PhaseId phaseId, Lifecycle lifecycle, FacesContext context) {
          PhaseEvent beforePhaseEvent = new PhaseEvent(context, phaseId, lifecycle);
          for (int i = 0; i < lifecycle.getPhaseListeners().length; i++) {
          PhaseListener listener = lifecycle.getPhaseListeners()[i];
          if (listener.getPhaseId() == phaseId || listener.getPhaseId() == PhaseId.ANY_PHASE) {
          listener.beforePhase(beforePhaseEvent);
          }
          }
          }
          }

          Step 2 - Configure the Dispacher Servlet viewResolver as follows:

          <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewR esolver">
          <property name="cache" value="false" />
          <property name="viewClass" value="javax.faces.mvc.view.FaceletView" />
          <property name="prefix" value="/WEB-INF/views/" />
          <property name="suffix" value=".xhtml" />
          </bean>

          Step 3 - Configure the faces-config

          <application>

          <variable-resolver>org.springframework.web.jsf.DelegatingVar iableResolver</variable-resolver>

          <el-resolver>org.springframework.web.jsf.el.SpringBean FacesELResolver</el-resolver>
          ......

          Step 4 - The HelloController

          @Controller
          public class HelloController {

          @RequestMapping("/hello")
          public ModelAndView hello(@RequestParam(value = "name", defaultValue = "Visitor") String name) {
          ModelAndView view = new ModelAndView("helloView");
          view.addObject("helloMessage", "Hello, " + name + "!");
          return view;
          }

          Step 5 - The Facelet View (/WEB-INF/views/helloView.xhtml)
          ....
          <h:head>
          <title>Hello Spring with FaceletResolverView</title>
          </h:head>
          <h:body>
          Hello ${helloMessage}
          </h:body>
          Last edited by isaac.silva; May 7th, 2010, 08:30 PM.

          Comment


          • #6
            Hi Isaac,

            Sorry for hijacking an old thread. I am trying your approach from this post. But it seems unable to map the request and I get 404 error ( I see no other issues in log or console). If you could share your example application, I will be grateful. Thanks in advance.

            Originally posted by isaac.silva View Post
            FaceletViewResolver = Spring MVC + Facelets

            Step 1 - Include the following class in your project:

            package javax.faces.mvc.view;

            imports ...

            public class FaceletView extends AbstractUrlBasedView {

            Comment


            • #7
              I know this thread is a little bit old, but I've created simple project that describe working Facelets with Spring MVC. Solution based on Isaac Silva https://github.com/acichon89/springmvcfacelets

              Comment

              Working...
              X