简单的SpringWebFlow例子及遇到的问题
这段时间在看《Spring 实战》里面有讲Spring Web Flow,觉得里面的例子过于复杂,不适合新手,于是在网上找了个例子,跟着写
以下是项目的目录,我是基于maven搭建项目的
pom.xml文件,插入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>SpringWebFlow</groupId> <artifactId>SpringWebFlow</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>SpringWebFlow Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!--SpringMVC所需要的依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.7.RELEASE</version> </dependency> <!--Spring Web Flow所需要的依赖--> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-binding</artifactId> <version>2.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-faces</artifactId> <version>2.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-js</artifactId> <version>2.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-js-resources</artifactId> <version>2.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-webflow</artifactId> <version>2.4.4.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> </project>
Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?> <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-2.5.xsd http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd"> <!-- 创建流程执行器,默认表示引用bean id为 'flowRegistry'的流程注册表--> <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/> <!-- 注册流程注册表 --> <webflow:flow-registry id="flowRegistry"> <webflow:flow-location path="/WEB-INF/flows/hello.xml" id="hello" /> </webflow:flow-registry> <!--作用:帮助DispatcherServlet将流程请求发送给Spring Web Flow--> <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"> <property name="flowRegistry" ref="flowRegistry"/> </bean> <!--作用:等同于controller,它会响应发送的流程请求并对其进行处理--> <bean id="flowHandlerAdapter" class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> <property name="flowExecutor" ref="flowExecutor"/> </bean> </beans>
此时流程注册表和jsp文件在同一个文件夹下面,所以不需要配置视图解析器和视图工厂
web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>FlowServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring-wf.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>FlowServlet</servlet-name> <url-pattern>*.flow</url-pattern> </servlet-mapping> </web-app>
流程注册表
<?xml version="1.0" encoding="UTF-8"?> <flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"> <view-state id="cart" > <transition on="submit" to="order"> </transition> </view-state> <view-state id="order"> <transition on="confirm" to="finish"> </transition> </view-state> <view-state id="finish"> <transition on="toindex" to="index"> </transition> </view-state> <end-state id="index" view="externalRedirect:index.jsp"> </end-state> </flow>
<view-state>,如果只有id属性的时候,会在流程文件所在的文件夹寻找id名字的jsp文件作为view。如果明确指定view属性的话,就找这个名字的jsp文件
各种jsp文件
index.jsp
<%-- Created by IntelliJ IDEA. User: I am master Date: 2017/5/2 Time: 14:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h2 align="center">Hello,WebFlow</h2><br/> Item1:<a href="hello.flow">加入购物车</a><br/> Item2:<a href="hello.flow">加入购物车</a><br/> Item2:<a href="hello.flow">加入购物车</a> </body> </html>
cart.jsp
<%-- Created by IntelliJ IDEA. User: I am master Date: 2017/5/2 Time: 14:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h2 align="center">购物车</h2><br/> 衣服:<a href="${flowExecutionUrl}&_eventId=submit">买买买!!!</a><br/> 裤子:<a href="${flowExecutionUrl}&_eventId=submit">买买买!!!</a><br/> 鞋子:<a href="${flowExecutionUrl}&_eventId=submit">买买买!!!</a> </body> </html>
order.jsp
<%-- Created by IntelliJ IDEA. User: I am master Date: 2017/5/2 Time: 14:45 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h2 align="center">订单</h2><br/> <a href="${flowExecutionUrl}&_eventId=confirm">确认支付</a> </body> </html>
finish.jsp
<%-- Created by IntelliJ IDEA. User: I am master Date: 2017/5/2 Time: 14:45 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h2 align="center">确认支付</h2><br/> <a href="${flowExecutionUrl}&_eventId=toindex">恭喜你,支付成功..</a> </body> </html>
运行结果
遇到的问题:
自己写完以后,运行不起来,报404
表达式没有解析,一开始以为是缺少jar包,胡乱加了很多不必要的jar包,但是还是没有解决
错误原因:maven搭建项目web.xml文件默认的版本是2.3,但是我们需要的是3.1,因此将web.xml改为3.1的版本就可以了
很多情况下,我们会将流程注册表和jsp放在不同的文件夹下,这就需要视图解析器和视图工厂
则Spring的配置文件应该为如下
<?xml version="1.0" encoding="UTF-8"?> <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-2.5.xsd http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd"> <!-- 流程注册器 隐含一句 flow-registry="flowRegistry" 默认表示引用bean id为 'flowRegistry'的流程注册表--> <webflow:flow-executor id="flowExecutor" /> <!-- 流程注册表 --> <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices"> <webflow:flow-location path="/WEB-INF/flows/hello.xml" id="hello" /> </webflow:flow-registry> <!-- WebFlow 视图解析器 --> <bean id="flowViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"> </property> <property name="prefix" value="/WEB-INF/flowView/"> </property> <property name="suffix" value=".jsp"> </property> </bean> <!-- WebFlow 视图工厂构建服务 --> <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" /> <!-- WebFlow 视图工厂创建器,表示使用视图解析器将流程配置(xml)中的逻辑视图交给视图解析器解析 → jsp --> <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator"> <property name="viewResolvers" ref="flowViewResolver" /> </bean> <!-- 配置WebFlow 处理器映射器--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- 这个逻辑视图名的 前缀 必须与流程注册表中的 webflow:flow-location 的 id一致, 而 后缀 必须是当前DispatcherServlet匹配的地址,也就是 必须以.flow结束,否则不被前端控制器处理(视图名必须匹配*.flow) --> <!-- 这里代表将请求路径为hello.flow的url交给flowController处理 --> <prop key="hello.flow">flowController</prop> </props> </property> </bean> <!--WebFlow 处理器,根据逻辑视图名到流程执行器中找到对应的注册表,进而找到流程配置文件,转到不同的物理视图--> <!--主要工作就是负责将url转化成逻辑视图交给视图解析器解析 → jsp--> <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController"> <property name="flowExecutor" ref="flowExecutor" /> </bean> </beans>
小结:
相同点:SpringMVC和流程都实现了mvc设计模式
不同点:在mvc设计模式的实现方面不同
SpringMVC通过编写controller,service类来实现
而流程则通过bean来实现,底层已经帮你实现了,帮你来处理请求跳转到对应的视图界面