1.6 Struts 2应用改进
为了让之前编写的Struts 2应用更接近实际的项目开发,接下来将对该应用进行升级。
1.6.1 改进表单
改进表单的主要工作内容是使用Struts 2的表单标签。首先需要引入Struts标签库,然后将HTML表单标签替换为Struts 2的表单标签。
<%@ taglib prefix="s" uri="/struts-tags" %> <s:form action="login" method="post"> <s:textfield name="email" label="Email" /> <s:password name="password" label="密码"></s:password> <s:submit value="确认"></s:submit> </s:form>
这样看起来,这些改变并没什么特别,但当使用浏览器访问该页面并查看页面源码的时候,就会发现得到的页面源码片段如下:
<form id="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793" name="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793" action="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793" method="post"> <table class="wwFormTable"> <tr> <td class="tdLabel"> <label for="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793_email" class="label">Email:</label> </td> <td><input type="text" name="email" value="" id="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793_email" /> </td> </tr> <tr> <td class="tdLabel"> <label for="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793_password" class="label">密码:</label> </td> <td><input type="password" name="password" id="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793_password" /> </td> </tr> <tr> <td colspan="2"> <div align="right"> <input type="submit" id="login;jsessionid=D9AEF908F6139FCD72DD2FABFAEC5793_0" value="确认" /> </div> </td> </tr> </table> </form>
仔细阅读代码之后,会发现这段源码有以下特点:
(1)出现了jsessionid标志,它是用于跟踪会话的标志,如果客户端禁用了cookie也能保证HttpSession有效。
(2)表单自动采用了表格布局并添加了CSS样式。如果开发人员不喜欢表格布局,可以自定义主题风格,但在目前,表格对齐了label所指定的文字和右端的输入框,对于要求不高的Java程序员来说,这已经足够好了。
下面列举了Struts 2的常见表单标签。
form:对应一个表单元素。
textfield:对应一个单行文本框。
password:对应一个密码输入框。
radio:对应一个单选框元素。
checkbox:对应一个复选框元素。
select:对应一个下拉列表框。
textarea:对应一个多行文本域。
reset:对应一个重设按钮。
submit:对应一个提交按钮。
1.6.2 改进Action
● 让Action类实现Action接口
Action接口是Struts 2框架提供的,先来看一下Action接口的定义。
public interface Action { public static final String SUCCESS = "success"; public static final String NONE = "none"; public static final String ERROR = "error"; public static final String INPUT = "input"; public static final String LOGIN = "login"; public String execute() throws Exception; }
Action接口定义了5个标准字符串常量,它们分别是SUCCESS、NONE、ERROR、INPUT和LOGIN,使用它们可以简化execute()方法的返回值,并可以使execute()方法的返回值标准化。如果处理成功,则返回SUCCESS常量,避免直接返回一个success字符串。因此,可以将原来的LoginAction代码进行如下的修改:
public class LoginAction implements Action{ public String execute(){ if(email.equals("z@163.com")&&password.equals("123456")) return SUCCESS; else return ERROR; } … }
● 继承ActionSupport类
ActionSupport是Action接口的一个实现类,如果编写的Action继承自ActionSupport类,不仅能获得Action接口的好处,还能获得更多的便利。例如ActionSupport类提供的getText()方法支持国际化与本地化功能,其具体内容暂不探讨。
1.6.3 向视图共享数据
在Servlet中,要向下一个JSP页面共享数据,需要调用request.setAttribute()方法,而在Struts 2的Action中就简单多了,Action的属性可以在下一个视图中直接访问。之前的例子中,email就是LoginAction的一个属性,基于上面的介绍,此处可以在index.jsp页面中直接访问这个属性。
您已经登录!欢迎光临,<s:property value="email"/>
其中,<s:property>标签可以简单理解为用于访问Action的属性。
可能有人会认为这是一种特殊情况,因为email本身就是表单参数,那么能不能在结果视图中访问Action的其他属性呢?
现在给LoginAction新增一个name属性(name域成员及getter&setter方法),然后在execute()方法中为其赋值,最后在index.jsp中获取name的值。此时LoginAction的代码如下:
public class LoginAction extends ActionSupport{ public String execute(){ if(email.equals("z@163.com")&&password.equals("123456")){ setName("zhangsan"); return SUCCESS; }else return ERROR; } private String email; private String password; private String name; … }
index.jsp的代码如下:
您已经登录!欢迎光临,<s:property value="name"/>
访问login.jsp,正确输入用户名和密码,浏览器会显示“您已经登录!欢迎光临,zhangsan”。通过这个例子,提醒用户,Action中的成员属性,并不一定都是用于封装请求参数,也可以用来封装需要传入下一个JSP页面的数据。