Remove remaining Portlet references
Issue: SWF-1692
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
* Copyright 2004-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,17 +18,17 @@ package org.springframework.faces.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for the resources tag.
|
||||
@@ -39,101 +39,57 @@ import org.w3c.dom.Element;
|
||||
*/
|
||||
public class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
static final String SERVLET_RESOURCE_HANDLER_BEAN_NAME = "jsfResourceRequestHandler";
|
||||
|
||||
static final String PORTLET_RESOURCE_HANDLER_BEAN_NAME = "jsfPortletResourceRequestHandler";
|
||||
private static final String SERVLET_RESOURCE_HANDLER_BEAN_NAME = "jsfResourceRequestHandler";
|
||||
|
||||
private static final boolean isRichFacesPresent =
|
||||
ClassUtils.isPresent("org.richfaces.application.CoreConfiguration",
|
||||
ResourcesBeanDefinitionParser.class.getClassLoader());
|
||||
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
new ServletRegistrar(element, parserContext).register();
|
||||
if (JsfRuntimeInformation.isSpringPortletPresent()) {
|
||||
new PortletRegistrar(element, parserContext).register();
|
||||
}
|
||||
Object source = parserContext.extractSource(element);
|
||||
registerHandlerAdapterIfNecessary(source, parserContext);
|
||||
registerResourceHandler(source, parserContext);
|
||||
registerHandlerMappings(element, source, parserContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static abstract class Registrar {
|
||||
|
||||
protected final Element element;
|
||||
|
||||
protected final ParserContext parserContext;
|
||||
|
||||
protected final Object source;
|
||||
|
||||
public Registrar(Element element, ParserContext parserContext) {
|
||||
this.element = element;
|
||||
this.parserContext = parserContext;
|
||||
this.source = parserContext.extractSource(element);
|
||||
private void registerHandlerAdapterIfNecessary(Object source, ParserContext parserContext) {
|
||||
String beanName = "org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter";
|
||||
if (parserContext.getRegistry().containsBeanDefinition(beanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
public abstract void register();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
private static class ServletRegistrar extends Registrar {
|
||||
|
||||
public ServletRegistrar(Element element, ParserContext parserContext) {
|
||||
super(element, parserContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
registerHandlerAdapterIfNecessary();
|
||||
registerResourceHandler();
|
||||
registerHandlerMappings();
|
||||
}
|
||||
|
||||
private void registerHandlerAdapterIfNecessary() {
|
||||
if (parserContext.getRegistry().containsBeanDefinition("org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter")) {
|
||||
return;
|
||||
}
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
private void registerResourceHandler() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition("org.springframework.faces.webflow.JsfResourceRequestHandler");
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(SERVLET_RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
|
||||
private void registerHandlerMappings() {
|
||||
Map<String, String> urlMap = new ManagedMap<String, String>();
|
||||
urlMap.put("/javax.faces.resource/**", SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
|
||||
if (isRichFacesPresent) {
|
||||
urlMap.put("/rfRes/**", SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
}
|
||||
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
beanDefinition.getPropertyValues().add("urlMap", urlMap);
|
||||
|
||||
String order = element.getAttribute("order");
|
||||
beanDefinition.getPropertyValues().add("order", StringUtils.hasText(order) ? order : 0);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
private void registerResourceHandler(Object source, ParserContext parserContext) {
|
||||
String beanName = "org.springframework.faces.webflow.JsfResourceRequestHandler";
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanName);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(SERVLET_RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
|
||||
private static class PortletRegistrar extends Registrar {
|
||||
private void registerHandlerMappings(Element element, Object source, ParserContext parserContext) {
|
||||
Map<String, String> urlMap = new ManagedMap<String, String>();
|
||||
urlMap.put("/javax.faces.resource/**", SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
|
||||
public PortletRegistrar(Element element, ParserContext parserContext) {
|
||||
super(element, parserContext);
|
||||
if (isRichFacesPresent) {
|
||||
urlMap.put("/rfRes/**", SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition("org.springframework.faces.webflow.context.portlet.JsfResourceRequestHandler");
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(PORTLET_RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
beanDefinition.getPropertyValues().add("urlMap", urlMap);
|
||||
|
||||
String order = element.getAttribute("order");
|
||||
beanDefinition.getPropertyValues().add("order", StringUtils.hasText(order) ? order : 0);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package org.springframework.faces.mvc;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isPortletRequest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
@@ -60,10 +57,7 @@ public class JsfView extends AbstractUrlBasedView {
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, this.facesLifecycle, facesContext);
|
||||
|
||||
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
|
||||
|
||||
if (!isPortletRequest(facesContext)) {
|
||||
viewHandler.initView(facesContext);
|
||||
}
|
||||
viewHandler.initView(facesContext);
|
||||
|
||||
UIViewRoot viewRoot = viewHandler.createView(facesContext, getUrl());
|
||||
Assert.notNull(viewRoot, "A JSF view could not be created for " + getUrl());
|
||||
|
||||
@@ -66,8 +66,7 @@ public class FacesContextHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that can be used to create a new default {@link FacesContext} instance for the running
|
||||
* (Portlet/Servlet) environment.
|
||||
* Factory method that can be used to create a new default {@link FacesContext} instance.
|
||||
*
|
||||
* @param context the native context
|
||||
* @param request the native request
|
||||
|
||||
@@ -20,10 +20,8 @@ import javax.faces.FacesWrapper;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Helper class to provide information about the JSF runtime environment such as
|
||||
@@ -80,12 +78,6 @@ public class JsfRuntimeInformation {
|
||||
private static boolean myFacesInUse = isMyFacesContextFactoryInUse();
|
||||
|
||||
|
||||
private static boolean portletPresent = ClassUtils.isPresent("javax.portlet.Portlet", CLASSLOADER);
|
||||
|
||||
private static boolean springPortletPresent =
|
||||
ClassUtils.isPresent("org.springframework.web.portlet.DispatcherPortlet", CLASSLOADER);
|
||||
|
||||
|
||||
|
||||
public static boolean isAtLeastJsf22() {
|
||||
return jsfVersion >= JSF_22;
|
||||
@@ -143,46 +135,4 @@ public class JsfRuntimeInformation {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the container has support for portlets and if Spring MVC portlet support is available
|
||||
*
|
||||
* @return <tt>true</tt> if a portlet environment is detected
|
||||
*/
|
||||
public static boolean isSpringPortletPresent() {
|
||||
return portletPresent && springPortletPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified {@link FacesContext} is from a portlet request.
|
||||
* @param context the faces context
|
||||
* @return <tt>true</tt> if the request is from a portlet
|
||||
*/
|
||||
public static boolean isPortletRequest(FacesContext context) {
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
return isPortletContext(context.getExternalContext().getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified {@link RequestContext} is from a portlet request.
|
||||
*
|
||||
* @param context the request context
|
||||
* @return <tt>true</tt> if the request is from a portlet
|
||||
*/
|
||||
public static boolean isPortletRequest(RequestContext context) {
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
return isPortletContext(context.getExternalContext().getNativeContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified context object is from portlet.
|
||||
*
|
||||
* @param nativeContext the native context
|
||||
* @return <tt>true</tt> if the context is from a portlet
|
||||
*/
|
||||
public static boolean isPortletContext(Object nativeContext) {
|
||||
Assert.notNull(nativeContext, "Context must not be null");
|
||||
return ClassUtils.getMethodIfAvailable(nativeContext.getClass(), "getPortletContextName") != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.springframework.webflow.execution.View;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isMojarraPresent;
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isPortletRequest;
|
||||
|
||||
/**
|
||||
* JSF-specific {@link ViewFactory} implementation.
|
||||
@@ -107,9 +106,7 @@ public class JsfViewFactory implements ViewFactory {
|
||||
|
||||
private ViewHandler getViewHandler(FacesContext facesContext) {
|
||||
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
|
||||
if (!isPortletRequest(facesContext)) {
|
||||
viewHandler.initView(facesContext);
|
||||
}
|
||||
viewHandler.initView(facesContext);
|
||||
return viewHandler;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
<factory>
|
||||
<application-factory>org.springframework.faces.webflow.FlowApplicationFactory</application-factory>
|
||||
<faces-context-factory>org.springframework.faces.webflow.context.portlet.PortletFacesContextFactory</faces-context-factory>
|
||||
</factory>
|
||||
|
||||
<lifecycle>
|
||||
|
||||
@@ -26,7 +26,7 @@ public abstract class AbstractResourcesConfigurationTests extends TestCase {
|
||||
Map<String, ?> map = this.context.getBeansOfType(HttpRequestHandlerAdapter.class);
|
||||
assertEquals(1, map.values().size());
|
||||
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
Object resourceHandler = this.context.getBean("jsfResourceRequestHandler");
|
||||
assertNotNull(resourceHandler);
|
||||
assertTrue(resourceHandler instanceof JsfResourceRequestHandler);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public class AbstractFlowConfiguration implements ApplicationContextAware {
|
||||
* @return the created builder
|
||||
*/
|
||||
protected FlowExecutorBuilder getFlowExecutorBuilder(FlowDefinitionLocator flowRegistry) {
|
||||
return new FlowExecutorBuilder(flowRegistry, this.applicationContext);
|
||||
return new FlowExecutorBuilder(flowRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ public class AbstractFlowConfiguration implements ApplicationContextAware {
|
||||
* @return the created builder
|
||||
*/
|
||||
protected FlowBuilderServicesBuilder getFlowBuilderServicesBuilder() {
|
||||
return new FlowBuilderServicesBuilder(this.applicationContext);
|
||||
return new FlowBuilderServicesBuilder();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,21 +52,17 @@ public class FlowBuilderServicesBuilder {
|
||||
private boolean enableDevelopmentMode;
|
||||
|
||||
|
||||
public FlowBuilderServicesBuilder() {
|
||||
this.viewFactoryCreator = new MvcViewFactoryCreator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with the given ApplicationContext.
|
||||
*
|
||||
* @param applicationContext the ApplicationContext to use to initialize a
|
||||
* default ViewFactoryCreator instance with.
|
||||
* @deprecated as of 2.5 an ApplicationContext is no longer required
|
||||
*/
|
||||
public FlowBuilderServicesBuilder(ApplicationContext applicationContext) {
|
||||
Assert.notNull(applicationContext, "applicationContext is required");
|
||||
this.viewFactoryCreator = initViewFactoryCreator(applicationContext);
|
||||
}
|
||||
|
||||
private static ViewFactoryCreator initViewFactoryCreator(ApplicationContext applicationContext) {
|
||||
MvcViewFactoryCreator viewFactoryCreator = new MvcViewFactoryCreator();
|
||||
viewFactoryCreator.setApplicationContext(applicationContext);
|
||||
return viewFactoryCreator;
|
||||
this.viewFactoryCreator = new MvcViewFactoryCreator();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.webflow.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -67,7 +66,7 @@ public class FlowDefinitionRegistryBuilder {
|
||||
/**
|
||||
* Create a new instance with the given ApplicationContext.
|
||||
*
|
||||
* @param applicationContext the ApplicationContext to use for initializing the
|
||||
* @param appContext the ApplicationContext to use for initializing the
|
||||
* FlowDefinitionResourceFactory and FlowBuilderServices instances with
|
||||
*/
|
||||
public FlowDefinitionRegistryBuilder(ApplicationContext appContext) {
|
||||
@@ -77,7 +76,7 @@ public class FlowDefinitionRegistryBuilder {
|
||||
/**
|
||||
* Create a new instance with the given ApplicationContext and {@link FlowBuilderServices}.
|
||||
*
|
||||
* @param applicationContext the ApplicationContext to use for initializing the
|
||||
* @param appContext the ApplicationContext to use for initializing the
|
||||
* FlowDefinitionResourceFactory and FlowBuilderServices instances with
|
||||
* @param builderServices a {@link FlowBuilderServices} instance to configure
|
||||
* on the FlowDefinitionRegistry
|
||||
@@ -89,7 +88,7 @@ public class FlowDefinitionRegistryBuilder {
|
||||
this.flowBuilderServices = builderServices;
|
||||
}
|
||||
else {
|
||||
this.flowBuilderServices = new FlowBuilderServicesBuilder(appContext).build();
|
||||
this.flowBuilderServices = new FlowBuilderServicesBuilder().build();
|
||||
this.flowBuilderServices.setApplicationContext(appContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.springframework.webflow.execution.repository.snapshot.SerializedFlowE
|
||||
import org.springframework.webflow.execution.repository.snapshot.SimpleFlowExecutionSnapshotFactory;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.executor.FlowExecutorImpl;
|
||||
import org.springframework.webflow.mvc.builder.MvcEnvironment;
|
||||
|
||||
/**
|
||||
* A builder for {@link FlowExecutor} instances designed for programmatic use in
|
||||
@@ -50,8 +49,6 @@ public class FlowExecutorBuilder {
|
||||
|
||||
private Integer maxFlowExecutionSnapshots;
|
||||
|
||||
private MvcEnvironment environment;
|
||||
|
||||
private LocalAttributeMap<Object> executionAttributes = new LocalAttributeMap<Object>();
|
||||
|
||||
private ConditionalFlowExecutionListenerLoader listenerLoader;
|
||||
@@ -61,18 +58,21 @@ public class FlowExecutorBuilder {
|
||||
private ConversationManager conversationManager;
|
||||
|
||||
|
||||
public FlowExecutorBuilder(FlowDefinitionLocator flowRegistry) {
|
||||
Assert.notNull(flowRegistry, "FlowDefinitionLocator is required");
|
||||
this.flowRegistry = flowRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with the given flow registry and ApplicationContext.
|
||||
*
|
||||
* @param flowRegistry the flow registry that will locate flow definitions
|
||||
* @param applicationContext the Spring ApplicationContext to use for
|
||||
* initializing an instance of {@link MvcEnvironment}
|
||||
* @param applicationContext the Spring ApplicationContext
|
||||
* @deprecated as of 2.5 an ApplicationContext is no longer required
|
||||
*/
|
||||
public FlowExecutorBuilder(FlowDefinitionLocator flowRegistry, ApplicationContext applicationContext) {
|
||||
Assert.notNull(flowRegistry, "FlowDefinitionLocator is required");
|
||||
Assert.notNull(applicationContext, "applicationContext is required");
|
||||
this.flowRegistry = flowRegistry;
|
||||
this.environment = MvcEnvironment.environmentFor(applicationContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,10 +216,10 @@ public class FlowExecutorBuilder {
|
||||
private LocalAttributeMap<Object> getExecutionAttributes() {
|
||||
LocalAttributeMap<Object> attributes = new LocalAttributeMap<Object>(this.executionAttributes.asMap());
|
||||
if (!attributes.contains("alwaysRedirectOnPause")) {
|
||||
attributes.put("alwaysRedirectOnPause", (this.environment != MvcEnvironment.PORTLET));
|
||||
attributes.put("alwaysRedirectOnPause", true);
|
||||
}
|
||||
if (!attributes.contains("redirectInSameState")) {
|
||||
attributes.put("redirectInSameState", (this.environment != MvcEnvironment.PORTLET));
|
||||
attributes.put("redirectInSameState", true);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@@ -17,15 +17,12 @@ package org.springframework.webflow.config;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.service.DefaultConversionService;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.webflow.conversation.ConversationManager;
|
||||
@@ -45,7 +42,6 @@ import org.springframework.webflow.execution.repository.snapshot.SerializedFlowE
|
||||
import org.springframework.webflow.execution.repository.snapshot.SimpleFlowExecutionSnapshotFactory;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.executor.FlowExecutorImpl;
|
||||
import org.springframework.webflow.mvc.builder.MvcEnvironment;
|
||||
|
||||
/**
|
||||
* This factory encapsulates the construction and assembly of a {@link FlowExecutor}, including the provision of its
|
||||
@@ -57,8 +53,7 @@ import org.springframework.webflow.mvc.builder.MvcEnvironment;
|
||||
* @author Keith Donald
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, ApplicationContextAware, BeanClassLoaderAware,
|
||||
InitializingBean {
|
||||
class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, BeanClassLoaderAware, InitializingBean {
|
||||
|
||||
private static final String ALWAYS_REDIRECT_ON_PAUSE = "alwaysRedirectOnPause";
|
||||
|
||||
@@ -80,8 +75,6 @@ class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, ApplicationC
|
||||
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
private MvcEnvironment environment;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
@@ -133,12 +126,6 @@ class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, ApplicationC
|
||||
this.conversationManager = conversationManager;
|
||||
}
|
||||
|
||||
// implementing ApplicationContextAware
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
environment = MvcEnvironment.environmentFor(applicationContext);
|
||||
}
|
||||
|
||||
// implement BeanClassLoaderAware
|
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
@@ -186,12 +173,10 @@ class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, ApplicationC
|
||||
|
||||
private void putDefaultFlowExecutionAttributes(LocalAttributeMap<Object> executionAttributes) {
|
||||
if (!executionAttributes.contains(ALWAYS_REDIRECT_ON_PAUSE)) {
|
||||
Boolean redirect = (environment != MvcEnvironment.PORTLET);
|
||||
executionAttributes.put(ALWAYS_REDIRECT_ON_PAUSE, redirect);
|
||||
executionAttributes.put(ALWAYS_REDIRECT_ON_PAUSE, true);
|
||||
}
|
||||
if (!executionAttributes.contains(REDIRECT_IN_SAME_STATE)) {
|
||||
Boolean redirect = (environment != MvcEnvironment.PORTLET);
|
||||
executionAttributes.put(REDIRECT_IN_SAME_STATE, redirect);
|
||||
executionAttributes.put(REDIRECT_IN_SAME_STATE, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ public interface ExternalContext {
|
||||
* session and accessible to both internal and external SWF artifacts.
|
||||
* <p>
|
||||
* Note: most external context implementations do not distinguish between the concept of a "local" user session
|
||||
* scope and a "global" session scope. The Portlet world does, but not the Servlet for example. In those cases
|
||||
* calling this method returns the same map as calling {@link #getSessionMap()}.
|
||||
* scope and a "global" session scope. Otherwise this method returns the same map as calling {@link #getSessionMap()}.
|
||||
* @return the mutable global session attribute map
|
||||
*/
|
||||
public SharedAttributeMap<Object> getGlobalSessionMap();
|
||||
@@ -140,8 +139,7 @@ public interface ExternalContext {
|
||||
|
||||
/**
|
||||
* Is a <i>render</i> response allowed to be written for this request? Always return false after a response has been
|
||||
* completed. May return false before that to indicate a response is not allowed to be completed. For example, in a
|
||||
* Portlet environment, render responses are only allowed in render requests.
|
||||
* completed. May return false before that to indicate a response is not allowed to be completed.
|
||||
* @return true if yes, false otherwise
|
||||
*/
|
||||
public boolean isResponseAllowed();
|
||||
@@ -215,4 +213,4 @@ public interface ExternalContext {
|
||||
*/
|
||||
public boolean isResponseCompleteFlowExecutionRedirect();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shared classes used by the Servlet and Portlet ExternalContext implementations.
|
||||
* Shared classes used with Servlet or alternative ExternalContext implementations.
|
||||
*/
|
||||
package org.springframework.webflow.context.web;
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
* <p>
|
||||
* This class and the rest of the Spring Web Flow (SWF) engine have been designed with minimal dependencies on other
|
||||
* libraries. Spring Web Flow is usable in a standalone fashion. The engine system is fully usable outside an HTTP
|
||||
* servlet environment, for example in portlets, tests, or standalone applications. One of the major architectural
|
||||
* servlet environment, for example in tests, or standalone applications. One of the major architectural
|
||||
* benefits of Spring Web Flow is the ability to design reusable, high-level controller modules that may be executed in
|
||||
* <i>any</i> environment.
|
||||
* <p>
|
||||
|
||||
@@ -49,7 +49,7 @@ import org.springframework.webflow.definition.TransitionDefinition;
|
||||
* The web flow system will ensure that a RequestContext object is local to the current thread. It can be safely
|
||||
* manipulated without needing to worry about concurrent access.
|
||||
* <p>
|
||||
* Note: this request context is in no way linked to an HTTP or Portlet request. It uses the familiar "request" naming
|
||||
* Note: this request context is in no way linked to an HTTP request. It uses the familiar "request" naming
|
||||
* convention to indicate a single call to manipulate a runtime execution of a flow definition.
|
||||
*
|
||||
* @author Keith Donald
|
||||
@@ -151,7 +151,7 @@ public interface RequestContext {
|
||||
* constructs within that environment.
|
||||
* <p>
|
||||
* In addition, this context may be downcastable to a specific context type for a specific client environment, such
|
||||
* as Servlets or Portlets. Such downcasting will give you full access to a native HttpServletRequest, for example.
|
||||
* as Servlets. Such downcasting will give you full access to a native HttpServletRequest, for example.
|
||||
* With that said, for portability reasons you should avoid coupling your flow artifacts to a specific deployment
|
||||
* environment when possible.
|
||||
* @return the originating external context, the one that triggered the current execution request
|
||||
@@ -208,4 +208,4 @@ public interface RequestContext {
|
||||
*/
|
||||
public String getFlowExecutionUrl() throws IllegalStateException;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.mvc.builder;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Supported Spring Web MVC environments.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public enum MvcEnvironment {
|
||||
|
||||
/**
|
||||
* Spring Web Servlet MVC.
|
||||
*/
|
||||
SERVLET,
|
||||
|
||||
/**
|
||||
* Spring Web Portlet MVC.
|
||||
*/
|
||||
PORTLET;
|
||||
|
||||
/**
|
||||
* Calculates the web environment from the state of the provided application context.
|
||||
* @param applicationContext the application context
|
||||
* @return the web environment the context is running in, or null if not running in a web environment
|
||||
*/
|
||||
public static MvcEnvironment environmentFor(ApplicationContext applicationContext) {
|
||||
if (applicationContext instanceof WebApplicationContext) {
|
||||
return MvcEnvironment.SERVLET;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,6 @@ import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.beanwrapper.BeanWrapperExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.DefaultMessageCodesResolver;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
@@ -43,9 +41,6 @@ import org.springframework.webflow.validation.WebFlowMessageCodesResolver;
|
||||
* Returns {@link ViewFactory view factories} that create native Spring MVC-based views. Used by a FlowBuilder to
|
||||
* configure a flow's view states with Spring MVC-based view factories.
|
||||
* <p>
|
||||
* This implementation detects whether it is running in a Servlet or Portlet MVC environment, and returns instances of
|
||||
* the default view factory implementation for that environment.
|
||||
* <p>
|
||||
* By default, this implementation creates view factories that resolve their views by loading flow-relative resources,
|
||||
* such as .jsp templates located in a flow working directory. This class also supports rendering views resolved by
|
||||
* pre-existing Spring MVC {@link ViewResolver view resolvers}.
|
||||
@@ -57,9 +52,7 @@ import org.springframework.webflow.validation.WebFlowMessageCodesResolver;
|
||||
* @author Keith Donald
|
||||
* @author Scott Andrews
|
||||
*/
|
||||
public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationContextAware {
|
||||
|
||||
private MvcEnvironment environment;
|
||||
public class MvcViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
private FlowViewResolver flowViewResolver = new FlowResourceFlowViewResolver();
|
||||
|
||||
@@ -162,11 +155,6 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
this.messageCodesResolver = messageCodesResolver;
|
||||
}
|
||||
|
||||
// implementing ApplicationContextAware
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
environment = MvcEnvironment.environmentFor(applicationContext);
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration,
|
||||
@@ -188,17 +176,13 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a concrete instance of an AbstractMvcViewFactory according to the runtime environment (Servlet or
|
||||
* Portlet).
|
||||
* Creates a concrete instance of an AbstractMvcViewFactory.
|
||||
*/
|
||||
protected AbstractMvcViewFactory createMvcViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
if (environment == MvcEnvironment.SERVLET) {
|
||||
return new ServletMvcViewFactory(viewId, flowViewResolver, expressionParser, conversionService,
|
||||
binderConfiguration, messageCodesResolver);
|
||||
} else {
|
||||
throw new IllegalStateException("Web MVC Environment " + environment + " not supported ");
|
||||
}
|
||||
|
||||
return new ServletMvcViewFactory(viewId, flowViewResolver, expressionParser, conversionService,
|
||||
binderConfiguration, messageCodesResolver);
|
||||
}
|
||||
|
||||
public String getViewIdByConvention(String viewStateId) {
|
||||
|
||||
@@ -60,7 +60,7 @@ import org.springframework.webflow.validation.ValidationHelper;
|
||||
import org.springframework.webflow.validation.ValidationHintResolver;
|
||||
|
||||
/**
|
||||
* Base view implementation for the Spring Web MVC Servlet and Spring Web MVC Portlet frameworks.
|
||||
* Base view implementation for the Spring Web MVC Servlet frameworks.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
|
||||
@@ -47,8 +47,8 @@ import org.springframework.webflow.test.MockExternalContext;
|
||||
* <p>
|
||||
* A flow execution test can effectively automate and validate the orchestration required to drive an end-to-end
|
||||
* business task that spans several steps involving the user to complete. Such tests are a good way to test your system
|
||||
* top-down starting at the web-tier and pushing through all the way to the DB without having to deploy to a servlet or
|
||||
* portlet container. In addition, they can be used to effectively test a flow's execution (the web layer) standalone,
|
||||
* top-down starting at the web-tier and pushing through all the way to the DB without having to deploy to a servlet
|
||||
* container. In addition, they can be used to effectively test a flow's execution (the web layer) standalone,
|
||||
* typically with a mock service layer.
|
||||
*
|
||||
* @author Keith Donald
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<book xml:id="spring-framework-reference"
|
||||
xmlns="http://docbook.org/ns/docbook" version="5.0"
|
||||
xmlns:xl="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
|
||||
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
|
||||
xmlns="http://docbook.org/ns/docbook" version="5.0"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd">
|
||||
|
||||
<info>
|
||||
<title>Spring Web Flow Reference Guide</title>
|
||||
@@ -96,9 +93,7 @@
|
||||
<xi:include href="spring-mvc.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="spring-js.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="spring-faces.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="portlet.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="testing.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="upgrade-guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="flow-definition-field-mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
|
||||
</book>
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter xml:id="portlet"
|
||||
xmlns="http://docbook.org/ns/docbook" version="5.0"
|
||||
xmlns:xl="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
|
||||
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
|
||||
<title>Portlet Integration</title>
|
||||
<sect1 xml:id="portlet-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
This chapter shows how to use Web Flow in a Portlet environment.
|
||||
Spring Web Flow requires Portlet API 2.0 to run with.
|
||||
The <code>booking-portlet-mvc</code> sample application is a good reference for using Web Flow within a portlet.
|
||||
This application is a simplified travel site that allows users to search for and book hotel rooms.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-config-core">
|
||||
<title>Configuring web.xml and portlet.xml</title>
|
||||
<para>
|
||||
The configuration for a portlet depends on the portlet container used.
|
||||
The sample applications, included with Web Flow, are both configured to use <link xl:href="http://portals.apache.org/pluto/">Apache Pluto</link>.
|
||||
</para>
|
||||
<para>
|
||||
In general, the configuration requires adding a servlet mapping in the <code>web.xml</code> file to dispatch request to the portlet container.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<servlet>
|
||||
<servlet-name>swf-booking-mvc</servlet-name>
|
||||
<servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>portlet-name</param-name>
|
||||
<param-value>swf-booking-mvc</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>swf-booking-mvc</servlet-name>
|
||||
<url-pattern>/PlutoInvoker/swf-booking-mvc</url-pattern>
|
||||
</servlet-mapping>
|
||||
]]></programlisting>
|
||||
<para>
|
||||
The <code>portlet.xml</code> configuration is a standard portlet configuration.
|
||||
The <code>portlet-class</code> needs to be set along with a pair of <code>init-param</code>s.
|
||||
Setting the <code>expiration-cache</code> to <code>0</code> is recommended to force Web Flow to always render a fresh view.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<portlet>
|
||||
...
|
||||
<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
|
||||
<init-param>
|
||||
<name>contextConfigLocation</name>
|
||||
<value>/WEB-INF/web-application-config.xml</value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<name>viewRendererUrl</name>
|
||||
<value>/WEB-INF/servlet/view</value>
|
||||
</init-param>
|
||||
<expiration-cache>0</expiration-cache>
|
||||
...
|
||||
</portlet>
|
||||
]]></programlisting>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-config-spring">
|
||||
<title>Configuring Spring</title>
|
||||
<sect2 xml:id="portlet-config-spring-handler">
|
||||
<title>Flow Handlers</title>
|
||||
<para>
|
||||
The only supported mechanism for bridging a portlet request to Web Flow is a <code>FlowHandler</code>.
|
||||
The <code>PortletFlowController</code> used in Web Flow 1.0 is no longer supported.
|
||||
</para>
|
||||
<para>
|
||||
The flow handler, similar to the servlet flow handler, provides hooks that can:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>select the flow to execute</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>pass input parameters to the flow on initialization</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>handle the flow execution outcome</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>handle exceptions</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
The <code>AbstractFlowHandler</code> class is an implementation of <code>FlowHandler</code> that provides default implementations for these hooks.
|
||||
</para>
|
||||
<para>
|
||||
In a portlet environment the targeted flow id can not be inferred from the URL and must be defined explicitly in the handler.
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[
|
||||
public class ViewFlowHandler extends AbstractFlowHandler {
|
||||
public String getFlowId() {
|
||||
return "view";
|
||||
}
|
||||
}
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
<sect2 xml:id="portlet-config-spring-mappings">
|
||||
<title>Handler Mappings</title>
|
||||
<para>
|
||||
Spring Portlet MVC provides a rich set of methods to map portlet requests.
|
||||
Complete documentation is available in the <link xl:href="http://static.springframework.org/spring/docs/current/reference/portlet.html#portlet-handlermapping">Spring Reference Documentation</link>.
|
||||
</para>
|
||||
<para>
|
||||
The <code>booking-portlet-mvc</code> sample application uses a <code>PortletModeHandlerMapping</code> to map portlet requests.
|
||||
The sample application only supports <code>view</code> mode, but support for other portlet modes is available.
|
||||
Other modes can be added and point to the same flow as <code>view</code> mode, or any other flow.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="portletModeHandlerMapping"
|
||||
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
|
||||
<property name="portletModeMap">
|
||||
<map>
|
||||
<entry key="view">
|
||||
<bean class="org.springframework.webflow.samples.booking.ViewFlowHandler" />
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
<sect2 xml:id="portlet-config-spring-handler-adapter">
|
||||
<title>Flow Handler Adapter</title>
|
||||
<para>
|
||||
A <code>FlowHandlerAdapter</code> converts the handler mappings to the flow handlers.
|
||||
The flow executor is required as a constructor argument.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="flowHandlerAdapter"
|
||||
class="org.springframework.webflow.mvc.portlet.FlowHandlerAdapter">
|
||||
<property name="flowExecutor" ref="flowExecutor" />
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-views">
|
||||
<title>Portlet Views</title>
|
||||
<para>
|
||||
In order to facilitate view rendering, a <code>ViewRendererServlet</code> must be added to the <code>web.xml</code> file.
|
||||
This servlet is not invoked directly, but it used by Web Flow to render views in a portlet environment.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<servlet>
|
||||
<servlet-name>ViewRendererServlet</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>ViewRendererServlet</servlet-name>
|
||||
<url-pattern>/WEB-INF/servlet/view</url-pattern>
|
||||
</servlet-mapping>
|
||||
]]></programlisting>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-modes">
|
||||
<title>Portlet Modes and Window States</title>
|
||||
<sect2 xml:id="portlet-modes-state">
|
||||
<title>Window State</title>
|
||||
<para>
|
||||
The Portlet API defined three window states: normal, minimized and maximized.
|
||||
The portlet implementation must decide what to render for each of these window states.
|
||||
Web Flow exposes the string value of the window state under <code>portletWindowState</code> via the request map on the external context.
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[
|
||||
requestContext.getExternalContext().getRequestMap().get("portletWindowState");
|
||||
]]></programlisting>
|
||||
<programlisting><![CDATA[
|
||||
externalContext.requestMap.portletWindowState
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
<sect2 xml:id="portlet-modes-mode">
|
||||
<title>Portlet Mode</title>
|
||||
<para>
|
||||
The Portlet API defined three portlet modes: view, edit and help.
|
||||
The portlet implementation must decide what to render for each of these modes.
|
||||
Web Flow exposes the string value of the portlet mode under <code>portletMode</code> via the request map on the external context.
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[
|
||||
requestContext.getExternalContext().getRequestMap().get("portletMode");
|
||||
]]></programlisting>
|
||||
<programlisting><![CDATA[
|
||||
externalContext.requestMap.portletMode
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-jsf">
|
||||
<title>Using Portlets with JSF</title>
|
||||
<sect2 xml:id="portlet-jsf-using-portlet-jsf">
|
||||
<para>
|
||||
Prior to version 2.1 of Spring Web Flow, support for JSF Portlets was considered
|
||||
experimental and relied on a Portlet Bridge for JSF implementation.
|
||||
Furthermore JSR-329 (the latest specification in this area), which targets
|
||||
Portlet API 2.0 and JSF 1.2 environments at the time of writing is not yet
|
||||
final causing portlet bridge implementations to also remain incomplete.
|
||||
</para>
|
||||
<para>
|
||||
A closer comparison of Spring Web Flow and a Portlet Bridge for JSF shows
|
||||
the two have significant overlap. They both drive the
|
||||
JSF lifecycle and they both shield JSF from knowledge about Portlet action
|
||||
and render requests.
|
||||
</para>
|
||||
<para>
|
||||
Considering all of the above, starting with version 2.2, Spring Web Flow
|
||||
provides support for JSF Portlets using its own internal Portlet integration rather
|
||||
than a Portlet Bridge for JSF. We believe this will provide value for Web Flow users
|
||||
by reducing the number of dependencies in what is already a fairly complex
|
||||
combination of technologies with specifications lagging behind.
|
||||
</para>
|
||||
<para>
|
||||
What this practically means is the configuration required for JSF Portlets is
|
||||
very similar to what is alread documented in the rest of this chapter
|
||||
with the exception of <xref linkend="portlet-views"/>, which is not necessary
|
||||
with JSF.
|
||||
</para>
|
||||
<para>
|
||||
Review the <code>swf-booking-portlet-faces</code> sample in the Web Flow distribution
|
||||
for a working JSF Portlets example with complete configuration details. The main
|
||||
things to ensure are that the <code><faces:resources></code> elements is
|
||||
included as part of your Spring configuration and that your
|
||||
<code>faces-config.xml</code> configuration includes a <code>PortletViewHandler</code>:
|
||||
</para>
|
||||
|
||||
<programlisting language="java"><![CDATA[<?xml version="1.0"?>
|
||||
<!DOCTYPE faces-config PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
|
||||
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
|
||||
|
||||
<faces-config>
|
||||
<application>
|
||||
<view-handler>
|
||||
org.springframework.faces.webflow.context.portlet.PortletViewHandler
|
||||
</view-handler>
|
||||
</application>
|
||||
</faces-config>
|
||||
]]></programlisting>
|
||||
<para>
|
||||
The JSF Portlet support provided with Spring Web Flow requires JSF v2.0 or above. If
|
||||
you are upgrading from a previous release you should ensure that your <code>faces-config.xml</code>
|
||||
references <code>org.springframework.faces.webflow.context.portlet.PortletViewHandler</code> instead
|
||||
of <code>org.springframework.faces.webflow.application.portlet.PortletFaceletViewHandler</code>. You
|
||||
should also ensure that you have added <code><faces:resources></code> to you Spring configuration.
|
||||
</para>
|
||||
<para>
|
||||
Although JSF v2.0 is a minimum requirement, this has been primarily driven to provide better support in
|
||||
a Servlet environment. Many of the more advanced JSF 2.0 features (for example 'Partial State Saving')
|
||||
are not supported by Spring Web Flow in a Portlet environment.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="portlet-issues">
|
||||
<title>Issues in a Portlet Environment</title>
|
||||
<sect2 xml:id="portlet-issues-redirects">
|
||||
<title>Redirects</title>
|
||||
<para>
|
||||
The Portlet API only allows redirects to be requested from an action request.
|
||||
Because views are rendered on the render request, views and <code>view-state</code>s cannot trigger a redirect.
|
||||
</para>
|
||||
<para>
|
||||
The <code>externalRedirect:</code> view prefix is a convenience for Servlet based flows.
|
||||
An <code>IllegalStateException</code> is thrown if a redirect is requested from a render request.
|
||||
</para>
|
||||
<para>
|
||||
<code>end-state</code> redirects can be achieved by implementing <code>FlowHandler.handleExecutionOutcome</code>.
|
||||
This callback provides the <code>ActionResponse</code> object which supports redirects.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="portlet-issues-modes">
|
||||
<title>Switching Portlet Modes</title>
|
||||
<para>
|
||||
The portlet container passes the execution key from the previous flow when switching to a new mode.
|
||||
Even if the mode is mapped to a different <code>FlowHandler</code> the flow execution will resume the previous execution.
|
||||
You may switch the mode programatically in your FlowHandler after ending a flow in an ActionRequest.
|
||||
</para>
|
||||
<para>
|
||||
One way to start a new flow is to create a URL targeting the mode without the execution key.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
@@ -23,10 +23,6 @@ xsi:schemaLocation="
|
||||
JSF v2.0 or above. Both Sun Mojarra and Apache MyFaces runtime environments
|
||||
are supported.</para>
|
||||
|
||||
<para>Spring Web Flow also supports using JSF in a portlet environment.
|
||||
Spring Web Flow's portlet integration supports Portlets API 2.0.
|
||||
See <xref linkend="portlet" /> for more on Spring Web Flow's portlet
|
||||
integration.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="spring-faces-integration">
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter xml:id="upgrade-guide"
|
||||
xmlns="http://docbook.org/ns/docbook" version="5.0"
|
||||
xmlns:xl="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
|
||||
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd">
|
||||
<title>Upgrading from 1.0</title>
|
||||
<sect1 xml:id="upgrade-guide-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
This chapter shows you how to upgrade existing Web Flow 1 application to Web Flow 2.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 xml:id="upgrade-guide-definition-language">
|
||||
<title>Flow Definition Language</title>
|
||||
<para>
|
||||
The core concepts behind the flow definition language have not changed between Web Flow 1 and 2.
|
||||
However, some of the element and attribute names have changed.
|
||||
These changes allow for the language to be both more concise and expressive.
|
||||
A complete list of <link linkend="field-mappings">mapping changes</link> is available as an appendix.
|
||||
</para>
|
||||
<sect2 xml:id="upgrade-guide-definition-language-tool">
|
||||
<title>Flow Definition Updater Tool</title>
|
||||
<para>
|
||||
An automated tool is available to aid in the conversion of existing 1.x flows to the new 2.x style.
|
||||
The tool will convert all the old tag names to their new equivalents, if needed.
|
||||
While the tool will make a best effort attempt at conversion, there is not a one-to-one mapping for all version 1 concepts.
|
||||
If the tool was unable to convert a portion of the flow, it will be marked with a <code>WARNING</code> comment in the resulting flow.
|
||||
</para>
|
||||
<para>
|
||||
The conversion tool requires spring-webflow.jar, spring-core.jar and an XSLT 1.0 engine.
|
||||
<link xl:href="http://saxon.sourceforge.net/">Saxon 6.5.5</link> is recommended.
|
||||
</para>
|
||||
<para>
|
||||
The tool can be run from the command line with the following command.
|
||||
Required libraries must be available on the classpath.
|
||||
The source must be a single flow to convert.
|
||||
The resulting converted flow will be sent to standard output.
|
||||
</para>
|
||||
<programlisting>
|
||||
java org.springframework.webflow.upgrade.WebFlowUpgrader flow-to-upgrade.xml
|
||||
</programlisting>
|
||||
<sect3 xml:id="upgrade-guide-definition-language-tool-warnings">
|
||||
<title>Flow Definition Updater Tool Warnings</title>
|
||||
<sect4 xml:id="upgrade-guide-definition-language-tool-warnings-argument-parameter-type">
|
||||
<title>argument parameter-type no longer supported</title>
|
||||
<para>
|
||||
Bean actions have been deprecated in favor of EL based evaluate expressions.
|
||||
The EL expression is able to accept method parameters directly, so there is no longer a need for the argument tag.
|
||||
A side effect of this change is that method arguments must be of the correct type before invoking the action.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4 xml:id="upgrade-guide-definition-language-tool-warnings-inline-flow">
|
||||
<title>inline-flow is no longer supported</title>
|
||||
<para>
|
||||
Inline flows are no longer supported.
|
||||
The contents of the inline flow must be moved into a new top-level flow.
|
||||
The inline flow's content has been converted for your convenience.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4 xml:id="upgrade-guide-definition-language-tool-warnings-mapping-target-collection">
|
||||
<title>mapping target-collection is no longer supported</title>
|
||||
<para>
|
||||
Output mappings can no longer add an item to a collection.
|
||||
Only assignment is supported.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4 xml:id="upgrade-guide-definition-language-tool-warnings-var-bean">
|
||||
<title>var bean is no longer supported</title>
|
||||
<para>
|
||||
The var bean attribute is no longer needed.
|
||||
All spring beans can be resolved via EL.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4 xml:id="upgrade-guide-definition-language-tool-warnings-var-scope">
|
||||
<title>var scope is no longer supported</title>
|
||||
<para>
|
||||
The var element will place all variable into flow scope.
|
||||
Conversation scope was previously allowed.
|
||||
</para>
|
||||
</sect4>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-definition-language-el">
|
||||
<title>EL Expressions</title>
|
||||
<para>
|
||||
EL expressions are used heavily throughout the flow definition language.
|
||||
Many of the attributes that appear to be plain text are actually interpreted as EL.
|
||||
The standard EL delimiters (either ${} or #{} in Web Flow 2.0 or just #{} in Web Flow 2.1) are not necessary and will often cause an exception if they are included.
|
||||
</para>
|
||||
<para>
|
||||
EL delimiters should be removed where necessary by the updater tool.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="upgrade-guide-webflow-config">
|
||||
<title>Web Flow Configuration</title>
|
||||
<para>
|
||||
In Web Flow 1 there were two options available for configuring Web Flow, one using standard spring bean XML and the other using the <code>webflow-config-1.0</code> schema.
|
||||
The schema configuration option simplifies the configuration process by keeping long internal class names hidden and enabling contextual auto-complete.
|
||||
The schema configuration option is the only way to configure Web Flow 2.
|
||||
</para>
|
||||
<sect2 xml:id="upgrade-guide-webflow-config-beans">
|
||||
<title>Web Flow Bean Configuration</title>
|
||||
<para>
|
||||
The <code>FactoryBean</code> bean XML configuration method used in Web Flow 1 is no longer supported.
|
||||
The schema configuration method should be used instead.
|
||||
In particular beans defining <code>FlowExecutorFactoryBean</code> and <code>XmlFlowRegistryFactoryBean</code> should be updated.
|
||||
Continue reading Web Flow Schema Configuration for details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-config-schema">
|
||||
<title>Web Flow Schema Configuration</title>
|
||||
<para>
|
||||
The <code>webflow-config</code> configuration schema has also changed slightly from version 1 to 2.
|
||||
The simplest way to update your application is modify the version of the schema to 2.0 then fix any errors in a schema aware XML editor.
|
||||
The most common change is add 'flow-' to the beginning of the elements defined by the schema.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd">
|
||||
]]></programlisting>
|
||||
<sect3 xml:id="upgrade-guide-webflow-config-schema-executor">
|
||||
<title>flow-executor</title>
|
||||
<para>
|
||||
The flow executor is the core Web Flow configuration element.
|
||||
This element replaces previous <code>FlowExecutorFactoryBean</code> bean definitions.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<webflow:flow-executor id="flowExecutor" />
|
||||
]]></programlisting>
|
||||
</sect3>
|
||||
<sect3 xml:id="upgrade-guide-webflow-config-schema-listeners">
|
||||
<title>flow-execution-listeners</title>
|
||||
<para>
|
||||
Flow execution listeners are also defined in the flow executor.
|
||||
Listeners are defined using standard bean definitions and added by reference.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
|
||||
<webflow:flow-execution-listeners>
|
||||
<webflow:listener ref="securityFlowExecutionListener"/>
|
||||
</webflow:flow-execution-listeners>
|
||||
</webflow:flow-executor>
|
||||
|
||||
<bean id="securityFlowExecutionListener"
|
||||
class="org.springframework.webflow.security.SecurityFlowExecutionListener" />
|
||||
]]></programlisting>
|
||||
</sect3>
|
||||
<sect3 xml:id="upgrade-guide-webflow-config-schema-registry">
|
||||
<title>flow-registry</title>
|
||||
<para>
|
||||
The <code>flow-registry</code> contains a set of <code>flow-location</code>s.
|
||||
Every flow definition used by Web Flow must be added to the registry.
|
||||
This element replaces previous <code>XmlFlowRegistryFactoryBean</code> bean definitions.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<webflow:flow-registry id="flowRegistry">
|
||||
<webflow:flow-location path="/WEB-INF/hotels/booking/booking.xml" />
|
||||
</webflow:flow-registry>
|
||||
]]></programlisting>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-java-controller">
|
||||
<title>Flow Controller</title>
|
||||
<para>
|
||||
The package name for flow controllers has changed from <code>org.springframework.webflow.executor.mvc.FlowController</code> and is now <code>org.springframework.webflow.mvc.servlet.FlowController</code> for Servlet MVC requests.
|
||||
The portlet flow controller <code>org.springframework.webflow.executor.mvc.PortletFlowController</code> has been replaced by a flow handler adapter available at <code>org.springframework.webflow.mvc.portlet.FlowHandlerAdapter</code>.
|
||||
They will need to be updated in the bean definitions.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-java-url-handler">
|
||||
<title>Flow URL Handler</title>
|
||||
<para>
|
||||
The default URL handler has changed in Web Flow 2.
|
||||
The flow identifier is now derived from the URL rather then passed explicitly.
|
||||
In order to maintain comparability with existing views and URL structures a <code>WebFlow1FlowUrlHandler</code> is available.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean name="/pos.htm" class="org.springframework.webflow.mvc.servlet.FlowController">
|
||||
<property name="flowExecutor" ref="flowExecutor" />
|
||||
<property name="flowUrlHandler">
|
||||
<bean class="org.springframework.webflow.context.servlet.WebFlow1FlowUrlHandler" />
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-config-view-resolver">
|
||||
<title>View Resolution</title>
|
||||
<para>
|
||||
Web Flow 2 by default will both select and render views.
|
||||
View were previously selected by Web Flow 1 and then rendered by an external view resolver.
|
||||
</para>
|
||||
<para>
|
||||
In order for version 1 flows to work in Web Flow 2 the default view resolver must be overridden.
|
||||
A common use case is to use <link xl:href="http://tiles.apache.org/">Apache Tiles</link> for view resolution.
|
||||
The following configuration will replace the default view resolver with a Tiles view resolver.
|
||||
The <code>tilesViewResolver</code> in this example can be replaced with any other view resolver.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
|
||||
<web:flow-location path="..." />
|
||||
...
|
||||
</webflow:flow-registry>
|
||||
|
||||
<webflow:flow-builder-services id="flowBuilderServices"
|
||||
view-factory-creator="viewFactoryCreator"/>
|
||||
|
||||
<bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
|
||||
<property name="viewResolvers" ref="tilesViewResolver" />
|
||||
</bean>
|
||||
|
||||
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
|
||||
<property name="viewClass" value="org.springframework.web.servlet.view.tiles.TilesJstlView" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.web.servlet.view.tiles.TilesConfigurer">
|
||||
<property name="definitions" value="/WEB-INF/tiles-def.xml" />
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="upgrade-guide-webflow-concepts">
|
||||
<title>New Web Flow Concepts</title>
|
||||
<sect2 xml:id="upgrade-guide-webflow-concepts-binding">
|
||||
<title>Automatic Model Binding</title>
|
||||
<para>
|
||||
Web Flow 1 required Spring MVC based flows to manually call <code>FormAction</code> methods, notably:
|
||||
<code>setupForm</code>, <code>bindAndValidate</code> to process form views.
|
||||
Web Flow 2 now provides automatic model setup and binding using the <code>model</code> attribute for <code>view-state</code>s.
|
||||
Please see the <link linkend="view-model">Binding to a Model</link> section for details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-concepts-el-v-ognl">
|
||||
<title>OGNL vs Spring EL</title>
|
||||
<para>
|
||||
Web Flow 1 used OGNL exclusively for expressions within the flow definitions.
|
||||
Web Flow 2 adds support for Unified EL.
|
||||
Web Flow 2.1 uses Spring EL by default.
|
||||
United EL and OGNL can still be plugged in.
|
||||
Please see <xref linkend="el"/> for details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-concepts-flash-scope">
|
||||
<title>Flash Scope</title>
|
||||
<para>
|
||||
Flash scope in Web Flow 1 lived across the current request and into the next request.
|
||||
This was conceptually similar to Web Flow 2's view scope concept, but the semantics were not as well defined.
|
||||
In Web Flow 2, flash scope is cleared after every view render.
|
||||
This makes flashScope semantics in Web Flow consistent with other web frameworks.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-concepts-jsf">
|
||||
<title>JSF</title>
|
||||
<para>
|
||||
Web Flow 2 offers significantly improved integration with JSF.
|
||||
Please see <xref linkend="spring-faces"/> for details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="upgrade-guide-webflow-concepts-redirects">
|
||||
<title>External Redirects</title>
|
||||
<para>
|
||||
External redirects in Web Flow 1 were always considered context relative.
|
||||
In Web Flow 2, if the redirect URL begins with a slash, it is considered servlet-relative instead of context-relative.
|
||||
URLs without a leading slash are still context relative.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
@@ -77,9 +77,6 @@
|
||||
Upgraded projects will need to ensure that the <code><faces:resources></code> elements is
|
||||
included as part of their Spring configuration.
|
||||
</para>
|
||||
<para>
|
||||
See <xref linkend="portlet-jsf"/>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-deprecation">
|
||||
<title>Deprecations</title>
|
||||
@@ -97,83 +94,4 @@
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 xml:id="whatsnew-swf-230">
|
||||
<title>Spring Web Flow 2.3</title>
|
||||
<sect2 xml:id="whatsnew-swf-embedded-flow">
|
||||
<title>Embedding A Flow On A Page</title>
|
||||
<para>
|
||||
By default Web Flow does a client-side redirect upon entering every view state.
|
||||
That makes it impossible to embed a flow on a page or within a modal dialog and execute more than one view state without causing a full-page refresh.
|
||||
Web Flow now supports launching a flow in "embedded" mode.
|
||||
In this mode a flow can transition to other view states without a client-side redirect during Ajax requests.
|
||||
See <xref linkend="spring-mvc-embedded-flow"/> and <xref linkend="spring-faces-embedded-mode"/>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-jsr303">
|
||||
<title>Support For JSR-303 Bean Validation</title>
|
||||
<para>
|
||||
Support for the JSR-303 Bean Validation API is now available building on equivalent support available in Spring MVC.
|
||||
See <xref linkend="view-validate"/> for more details.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-pc-propagation">
|
||||
<title>Flow-Managed Persistence Context Propagation</title>
|
||||
<para>
|
||||
Starting with Web Flow 2.3 a flow managed <code>PersistenceContext</code> is automatically extended (propagated) to sub-flows assuming the subflow also has the feature enabled as well.
|
||||
See <xref linkend="flow-managed-persistence-propagation"/>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-portlet-resource-requests">
|
||||
<title>Portlet 2.0 Resource Requests</title>
|
||||
<para>
|
||||
Support for Portlet 2.0 resource requests has now been added enabling Ajax requests with partial rendering.
|
||||
URLs for such requests can be prepared with the <code><portlet:resourceURL></code> tag in JSP pages.
|
||||
Server-side processing is similar to a combined an action and a render requests but combined in a single request.
|
||||
Unlike a render request, the response from a resource request includes content from the target portlet only.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-conversation-manager">
|
||||
<title>Custom ConversationManager</title>
|
||||
<para>
|
||||
The <code><flow-execution-repository></code> element now provides a conversation-manager attribute accepting a reference to a ConversationManager instance.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-redirect-in-same-state">
|
||||
<title>Redirect In Same State</title>
|
||||
<para>
|
||||
By default Web Flow does a client-side redirect when remaining in the same view state as long as the current request is not an Ajax request.
|
||||
This is useful after form validation failure.
|
||||
Hitting Refresh or Back won't result in browser warnings.
|
||||
Hence this behavior is usually desirable.
|
||||
However a new flow execution attribute makes it possible to disable it and that may also be necessary in some cases specific to JSF applications.
|
||||
See <xref linkend="spring-faces-redirect-in-same-state"/>.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 xml:id="whatsnew-samples">
|
||||
<title>Samples</title>
|
||||
<para>
|
||||
The process for building the samples included with the distribution has been simplified.
|
||||
Maven can be used to build all samples in one step.
|
||||
Eclipse settings include source code references to simplify debugging.
|
||||
</para>
|
||||
<para>
|
||||
Additional samples can be accessed as follows:
|
||||
<programlisting language="xml">mkdir spring-samples
|
||||
cd spring-samples
|
||||
svn co https://src.springframework.org/svn/spring-samples/webflow-primefaces-showcase
|
||||
cd webflow-primefaces-showcase
|
||||
mvn package
|
||||
# import into Eclipse
|
||||
</programlisting>
|
||||
|
||||
<programlisting language="xml">mkdir spring-samples
|
||||
cd spring-samples
|
||||
svn co https://src.springframework.org/svn/spring-samples/webflow-showcase
|
||||
cd webflow-showcase
|
||||
mvn package
|
||||
# import into Eclipse
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user