PDA

View Full Version : how to configure spring MVC - view resolver - for facelets



r.krupinski
Jul 21st, 2006, 11:23 AM
Hello
How do I setup ViewResolver for Facelets?
I thought i could use InternalResourceView, but it seems it doesn't work



<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="cache" value="false" />
<property name="viewClass"
value="org.springframework.web.servlet.view.InternalResou rceView" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>

(.jsp is used for better eclipse support)

the error is


The requested resource (/jsf1/WEB-INF/servlet/view) is not available

Dave Syer
Oct 25th, 2006, 03:25 AM
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.



<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.

JavaGeek_Boston
Apr 9th, 2009, 12:32 PM
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

wt123
Apr 13th, 2009, 12:55 AM
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.

isaac.silva
May 7th, 2010, 07:21 PM
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.DelegatingVariableReso lver</variable-resolver>

<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELRe solver</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>

baskar
Aug 30th, 2012, 06:17 AM
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.


FaceletViewResolver = Spring MVC + Facelets

Step 1 - Include the following class in your project:

package javax.faces.mvc.view;

imports ...

public class FaceletView extends AbstractUrlBasedView {