2.5.3 添加处理信息
到目前为止,Action仅仅控制转发用户请求,JSP页面并未获得Action的处理结果。对于大部分Web应用而言,用户需要获得请求Action的处理结果。例如,在线购物系统需要查询某个种类下的商品,则 Action 调用业务逻辑组件的业务逻辑方法得到该种类下的全部商品,而JSP页面则获取该Action的处理结果,并将全部结果迭代输出。
下面为应用增加一个Action,该Action负责获取某个系列的全部书籍。为了让该Action可以获取这系列的书籍,我们增加一个业务逻辑组件,它包含一个业务逻辑方法,该方法可以获取某个系列的全部书籍。
下面是系统所用的业务逻辑组件的代码。
程序清单:codes\02\struts2qs2\WEB-INF\src\org\crazyit\struts2qs\service\BookService.java
public class BookService { //以数组模拟从持久存储设备(数据库)中取出的数据 private String[] books = new String[] { "疯狂Java讲义" , "疯狂Android讲义" , "轻量级Java EE企业应用实战", "疯狂Ajax讲义", "疯狂XML讲义", }; //业务逻辑方法,该方法返回全部图书 public String[] getLeeBooks() { return books; } }
上面的业务逻辑组件实际上就是MVC模式中的Model,它负责实现系统业务逻辑方法。理论上,业务逻辑组件实现业务逻辑方法时,必须依赖于底层的持久层组件,但此处的业务逻辑组件则只是返回一个静态的字符串数组——因为这只是一种模拟。
注意
此处的业务逻辑组件只是模拟实现业务逻辑方法,并未真正调用持久层组件来获取数据库信息。
在系统中增加如下Action类,该Action类先判断HTTP Session中的user属性是否存在且等于 crazyit 字符串——这要求在查看图书之前,用户必须已经登录本系统。如果用户已经登录本系统,则获取系统中的全部书籍,否则返回登录页面。新增的Action类的代码如下。
程序清单:codes\02\struts2qs2\WEB-INF\src\org\crazyit\struts2qs2\action\GetBooksAction.java
public class GetBooksAction implements Action { // 该属性并不用于封装用户请求参数 // 而用于封装Action需要输出到JSP页面的信息 private String[] books; // books属性的setter、getter方法 public void setBooks(String[] books) { this.books = books; } public String[] getBooks() { return books; } // 处理用户请求的execute方法 public String execute() throws Exception { // 获取Session中的user属性 String user = (String)ActionContext.getContext() .getSession().get("user"); // 如果user属性不为空,且该属性值为crazyit if (user != null && user.equals("crazyit")) { // 创建BookService实例 BookService bs = new BookService(); // 将业务逻辑组件的返回值设置成该Action的属性 setBooks(bs.getLeeBooks()); return SUCCESS; } else { return LOGIN; } } }
通过上面的Action类,我们发现Action类中的成员属性,并不一定用于封装用户请求参数,也可能是封装了Action需要传入下一个JSP页面中显示的属性。
提示:
Action中的成员属性,不一定用于封装用户请求参数,也可能是封装了Action需要传递到页面中显示的值。实际上,这些值将被封装在ValueStack对象中。
当控制器需要调用业务逻辑方法时,程序直接创建了一个业务逻辑组件实例,这并不是一种好的做法,因为控制器不应该关心业务逻辑组件的实例化过程。比较成熟的做法是可以利用工厂模式来管理业务逻辑组件;当然,目前最流行的方式是利用依赖注入——这将在与Spring整合的章节里介绍。
注意
在实际项目中,不会在控制器中直接创建业务逻辑组件实例,而是通过工厂模式管理业务逻辑组件实例,或者通过依赖注入将业务逻辑组件实例注入控制器组件。
该Action处理用户请求时,无须获得用户的任何请求参数。将该Action配置在struts.xml文件中,配置该Action的配置片段如下。
程序清单:codes\02\struts2qs2\WEB-INF\src\struts.xml
<!-- 定义获取图书的Action,对应实现类为org.crazyit.struts2qs.action.GetBooksAction--> <action name="getBooks" class="org.crazyit.struts2qs.action.GetBooksAction"> <!-- 如果处理结果返回login,则进入loginForm.jsp页面 --> <result name="login">/loginForm.jsp</result> <!-- 如果处理结果返回success,则进入showBook.jsp页面 --> <result name="success">/showBook.jsp</result> </action>
当用户向getBooks.action发送请求时,该请求将被转发给lee.GetBooksAction处理。