diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/FileNameBasedFlowUrlHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/FileNameBasedFlowUrlHandler.java new file mode 100644 index 00000000..a1b588c4 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/FileNameBasedFlowUrlHandler.java @@ -0,0 +1,75 @@ +/* + * 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.context.servlet; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.util.UrlPathHelper; +import org.springframework.web.util.WebUtils; +import org.springframework.webflow.mvc.servlet.FlowController; +import org.springframework.webflow.mvc.servlet.FlowHandler; + +/** + * + * A Web Flow < 2.0.4 compliant {@link FlowUrlHandler} implementation. Will be used by the {@link FlowController} + * implementation by default. Other custom {@link FlowHandler} implementations should use this implementation to keep + * the old URL schemes with Web Flow 2.0.4, whereas the last part of the URL is the flow id instead of the whole path. + * + *

+ * Expects URLs to launch flow to be of this pattern: + * + *

+ * http://<host>/[app context path]/[app servlet path]/[somePath]/<flow id>
+ * 
+ * + * For example: + * + *
+ * http://localhost/springtravel/app/booking/booking
+ * 
+ * + * Expects URLs to resume flows to be of this pattern: + * + *
+ * http://<host>/[app context path]/[app servlet path]/[somePath]/<flow id>?execution=<flow execution key>
+ * 
+ * + * For example: + * + *
+ * http://localhost/springtravel/app/booking/booking?execution=c1v1
+ * 
+ * + * + * Note: This class is available only for backwards compability of Web Flow 2.0.4 with older Web Flow + * 2.0 applications. Consider using the new Web Flow 2.0.4 URL ({@link DefaultFlowUrlHandler}) scheme to avoid flow id + * clashes inside the application. + * + * @author Agim Emruli + * + */ +public class FileNameBasedFlowUrlHandler extends DefaultFlowUrlHandler { + + private UrlPathHelper urlPathHelper; + + public FileNameBasedFlowUrlHandler() { + urlPathHelper = new UrlPathHelper(); + } + + public String getFlowId(HttpServletRequest request) { + return WebUtils.extractFilenameFromUrlPath(urlPathHelper.getLookupPathForRequest(request)); + } +} \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java index 16f69c25..8529ceee 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java @@ -28,6 +28,7 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.js.ajax.AjaxHandler; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; +import org.springframework.webflow.context.servlet.FileNameBasedFlowUrlHandler; import org.springframework.webflow.context.servlet.FlowUrlHandler; import org.springframework.webflow.executor.FlowExecutor; @@ -41,7 +42,7 @@ import org.springframework.webflow.executor.FlowExecutor; */ public class FlowController implements Controller, ApplicationContextAware, InitializingBean { - private FlowHandlerAdapter flowHandlerAdapter = new FlowHandlerAdapter(); + private FlowHandlerAdapter flowHandlerAdapter; private Map flowHandlers = new HashMap(); @@ -56,7 +57,8 @@ public class FlowController implements Controller, ApplicationContextAware, Init * @see #afterPropertiesSet() */ public FlowController() { - + flowHandlerAdapter = new FlowHandlerAdapter(); + flowHandlerAdapter.setFlowUrlHandler(new FileNameBasedFlowUrlHandler()); } /** @@ -108,8 +110,8 @@ public class FlowController implements Controller, ApplicationContextAware, Init * Set whether redirects sent by this controller should be compatible with HTTP 1.0 clients. *

* By default, this will enforce a redirect HTTP status code of 302 by delegating to - * HttpServletResponse.sendRedirect. Setting this to false will send HTTP status code 303, which is - * the correct code for HTTP 1.1 clients, but not understood by HTTP 1.0 clients. + * HttpServletResponse.sendRedirect. Setting this to false will send HTTP status code 303, which is the + * correct code for HTTP 1.1 clients, but not understood by HTTP 1.0 clients. *

* Many HTTP 1.1 clients treat 302 just like 303, not making any difference. However, some clients depend on 303 * when redirecting after a POST request; turn this flag off in such a scenario. diff --git a/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/FileNameBasedUrlHandlerTests.java b/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/FileNameBasedUrlHandlerTests.java new file mode 100644 index 00000000..5ec3f234 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/context/servlet/FileNameBasedUrlHandlerTests.java @@ -0,0 +1,48 @@ +/* + * 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.context.servlet; + +import junit.framework.TestCase; + +import org.springframework.mock.web.MockHttpServletRequest; + +public class FileNameBasedUrlHandlerTests extends TestCase { + + private DefaultFlowUrlHandler urlHandler = new FileNameBasedFlowUrlHandler(); + private MockHttpServletRequest request = new MockHttpServletRequest(); + + public void testGetFlowId() { + request.setContextPath("/springtravel"); + request.setServletPath("/app"); + request.setPathInfo("/foo"); + request.setRequestURI("/springtravel/app/foo"); + assertEquals("foo", urlHandler.getFlowId(request)); + } + + public void testGetFlowIdNoPathInfo() { + request.setContextPath("/springtravel"); + request.setServletPath("/app/foo.htm"); + request.setPathInfo(null); + request.setRequestURI("/springtravel/app/foo.htm"); + assertEquals("foo", urlHandler.getFlowId(request)); + } + + public void testGetFlowIdOnlyContextPath() { + request.setContextPath("/springtravel"); + request.setRequestURI("/springtravel"); + assertEquals("", urlHandler.getFlowId(request)); + } +} \ No newline at end of file