2.5.4 输出处理信息
如果用户没有登录,直接向getBooks Action发送请求,该请求将被转发到loginForm.jsp页面;如果用户已经登录,getBooks Action 将从系统中获取所有图书,并将请求转发给showBook.jsp页面。由showBook.jsp页面负责输出全部图书。
下面笔者将以最原始的方式,即JSP脚本来输出全部图书。
注意
在实际应用中,几乎绝对不会使用笔者这种方式来输出 Action 转发给 JSP输出的信息。但笔者为了让读者更清楚Struts 2标签库在底层所完成的动作,故此处使用JSP脚本来输出全部图书信息。
当 Action 设置了某个属性值后,Struts 2 将这些属性值全部封装在一个叫做struts.valueStack的请求属性里。
提示:
读者可能感到奇怪:笔者如何知道 Struts 2 将这些属性值封装在struts.valueStack 请求属性里呢?这一方面与编程经验有关;另一方面可以通过查看 Struts 2 的各种文档,最重要的一点是可以在 showBook.jsp 页面中通过getAttributeNames方法分析请求中的全部属性。
为了在 JSP 页面中输出需要输出的图书信息,我们可以通过如下代码来获取包含全部输出信息的ValueStack对象。
// 获取封装输出信息的ValueStack对象 request.getAttribute("struts.valueStack");
上面代码返回一个ValueStack对象,该对象封装了全部的输出信息。该对象是 Struts 2使用的一个ValueStack对象,可以通过OGNL表达式非常方便地访问该对象封装的信息。
从数据结构上来看,ValueStack有点类似于Map结构,但它比Map结构更加强大(因为它可以根据表达式来查询值)。Action的所有属性都被封装到ValueStack对象中,Action中的属性名可以理解为ValueStack中value的名字。
大致理解了ValueStack对象的结构后,我们可以通过如下代码来获取Action中设置的全部图书信息。
// 调用ValueStack的findValue方法查看某个表达式的值 vs.findValue("books");
理解了上面关键的两步,整个 JSP 页面的代码就比较容易理解了。下面是 showBook.jsp页面的代码。
程序清单:codes\02\struts2qs2\showBook.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@ page import="java.util.*,com.opensymphony.xwork2.util.*"%> <!DOCTYPE html> <html> <head> <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" /> <meta http-equiv="Content-Type" content="text/html; charset=GBK" /> <title>作者李刚的图书</title> </head> <body> <table border="1" width="360"> <caption>作者李刚的图书</caption> <% // 获取封装输出信息的ValueStack对象 ValueStack vs = (ValueStack)request .getAttribute("struts.valueStack"); // 调用ValueStack的findValue方法获取books属性值 String[] books = (String[])vs.findValue("books"); // 迭代输出全部图书信息 for (String book : books) { %> <tr> <td>书名:</td> <td><%=book%></td> </tr> <%}%> </table> </body> </html>
不可否认,上面 JSP 页面的代码是丑陋的,而且难以维护,因为里面嵌入了大量的 JSP脚本。但它对于读者理解Struts 2如何处理封装在Action中的ValueStack却很有帮助。
在浏览器中向getBooks.action发送请求,将看到如图2.5所示的页面。
图2.5 在JSP页面中输出Action的返回信息
通过上面页面,我们看到JSP页面已经输出了Struts 2控制器所返回的信息。上面整个过程,已经完全包括了Struts 2框架的三个部分:视图、控制器和模型。