3.5、Struts2实现用户登陆功能(重点)
在MyEclipse中,加入Struts2的支持。
加入支持jar包,这里只需要选择Struts2 Core核心支持库即可。
支持加入后,可以开始直接编写页面。
完成登陆的表单。
需要先导入标签库
<%@ taglib uri="/struts-tags" prefix="s"%> |
完成登陆界面。
<center> <s:form action="login" method="post"> 用户名:<s:textfield name="userid"></s:textfield> <br /> 密码:<s:password name="password"></s:password> <br /> <s:submit value="提交"></s:submit> <s:reset value="重置"></s:reset> </s:form> </center> |
下面建立Action,MyEclipse没有提供自动建立Action的工具,因此自己手工建立Class。
注意,Action类必须继承ActionSupport。
先完成接收参数和验证的操作
public class LoginAction extends ActionSupport {
private String userid; private String password;
public void validate() { // 编写验证操作 if (userid == null || userid.trim().equals("")) { // 添加操作信息 // 针对某一个页面元素出现的错误,使用FieldError保存 // ActionError则是由于某些业务或综合的问题导致的错误。 super.addFieldError("userid", "用户名不能为空!"); } if (password == null || password.trim().equals("")) { super.addFieldError("password", "密码不能为空!"); } } |
当验证通过后,要进入execute()方法,编写此方法。
public String execute() throws Exception { if (userid.equals("MLDN") && password.equals("123")) { // 登陆成功 return "suc"; } // 错误信息 super.addActionError("用户名或密码错误,请重新输入!"); return ActionSupport.INPUT; } |
手工加入此Action的配置,修改struts.xml
<!-- 包,里面放入多个<action> name:唯一标识,不允许重复 namespace:表示虚拟目录名称,也不允许重复 extends:继承关系,必须继承struts-default,否则无法使用 --> <package name="root" namespace="/" extends="struts-default"> <!-- 配置某一个action name:action访问的名称(不包含路径的名称) class:包.类名 --> <action name="login" class="cn.mldn.action.LoginAction"> <!-- 跳转路径 --> <result name="suc">/pages/suc.jsp</result> <result name="input">/index.jsp</result> </action> </package> |
编写suc.jsp
<center> 用户登陆成功!当前登陆用户为:${userid} </center> |
Action中的所有属性,会自动设置到request属性范围中。 |
测试时可以发现,Struts2的UI标签本身自带格式,自动包含一个表格,因此自己写的格式很容易乱。
如果想使用其自带格式,需要按照下面的代码编写
<center> <s:form action="login" method="post"> <s:textfield name="userid" label="用户名"></s:textfield> <s:password name="password" label="密码"></s:password> <s:submit value="提交"></s:submit> <s:reset value="重置"></s:reset> </s:form> </center> |
由于这种格式无法调整,因此开发中基本都不会使用自带的格式,而是使用原本普通程序时使用的格式。
想取消这个格式,需要在表单中加入以下内容
<s:form action="login" method="post" theme="simple"> |
使用这种格式后,就需要自己加入错误信息了。
可以使用s:fielderrors和s:actionerrors标签来显示错误信息。
<font color="red"> <s:fielderror></s:fielderror> <s:actionerror/> </font> |
这里是将错误信息统一显示,如果想单独显示,可以加入
用户名:<s:textfield name="userid"></s:textfield> <font color="red"> <s:fielderror fieldName="userid"></s:fielderror> </font> <br /> 密码:<s:password name="password"></s:password> <font color="red"> <s:fielderror fieldName="password"></s:fielderror> </font> |
但这样显示格式不好看,而且加入theme=simple也不起作用。
如果不想使用这种格式,只能自己使用EL表达式输出错误信息。
<center> <font color="red"> <c:if test="${actionErrors != null}"> <c:forEach var="e" items="${actionErrors}"> ${e } <br/> </c:forEach> </c:if> </font> <s:form action="login" method="post" theme="simple"> 用户名:<s:textfield name="userid"></s:textfield> <font color="red"> ${fieldErrors["userid"][0]} </font> <br /> 密码:<s:password name="password"></s:password> <font color="red"> ${fieldErrors["password"][0]} </font> <br /> <s:submit value="提交"></s:submit> <s:reset value="重置"></s:reset> </s:form> </center> |
在Struts2中出现的新的API:
ActionSupport:只需要在建立Action时,继承此类,并覆写validate和execute方法即可。
常用方法:
addFieldError:添加FieldError
addActionError:添加ActionError
登陆已经完成了,但如果登陆成功后,想将用户信息保存到session属性范围中,就需要再修改execute()方法的代码。
在Struts2中,保存属性范围属性的功能被封装了,可以通过以下方式来进行保存:
1) request范围:直接在Action中声明属性,并生成getter/setter方法,就自动放入到request范围中。
2) session范围:
// 向Session属性范围保存属性 ServletActionContext.getContext().getSession().put("user", userid); |
3) application范围
ServletActionContext.getContext().getApplication().put("user", userid); |
如果认为这种写法违背了自己的精神和习惯,也可以继续使用原有的setAttribute()的方法,也可以通过以下方法取得原本的内置对象。
HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); HttpSession session = request.getSession(); ServletContext application = ServletActionContext .getServletContext();
session.setAttribute("user", userid); |
3.6、Struts2的参数处理和资源配置(重点)
在Struts2中,也可以直接通过 对象.属性 的形式来接收参数,并自动将参数设置到vo中。
而且vo对象可以不实例化直接使用,Struts2自动完成实例化的操作。
public class User {
private String userid; private String password; |
页面上
用户名:<s:textfield name="user.userid"></s:textfield> 密码:<s:password name="user.password"></s:password> |
Action
public class LoginAction extends ActionSupport {
private User user;
|
如果是数字类型的参数,在Struts1可以自动接收并转换,如果输入的格式错误,不会提示错误,而是按照默认值处理。
在Struts2中,也可以自动接收并转型,而且如果输入的格式错误,还会自动提示错误信息。
但这里默认提示的错误信息,无法让用户看明白,必须自己修改这个提示信息。
而这个提示信息只能在资源文件中修改。
需要声明错误信息的资源文件,在Struts2里错误信息的资源文件可以按照以下三种方式定义:
1) 与Action同名的资源文件
2) package.properties,该包下的所有Action都可以调用这里的错误信息。
3) 全局资源文件,在src下任意命名,在需要在struts.properties中手工声明。
如果三个资源文件都在,错误信息的优先级:
Action同名 > package > 全局
错误信息格式:
invalid.fieldvalue.输入框的name
invalid.fieldvalue.user.age=年龄必须输入合法数字! |
如果是日期类型,Struts1无法自动转换,而在Struts2中可以自动转换了,而且格式错误也会自动提示。
在处理之前的错误信息时,多了一个struts.properties资源文件,该文件中主要用来进行Struts规定的各种配置,例如:
中文编码过滤
Struts2默认支持的编码是UTF-8,如果想修改,可以在struts.properties中加入以下配置
除了这种功能以外,还可以加入下面的配置:
加入此配置后,所有<s:form>的格式都默认按照simple来处理,可以不需要再手工在每个表单中加入这个配置了。
对于普通的保存错误信息的资源文件来说,除了可以声明自动转换时的错误,也可以像Struts1一样,声明验证的错误信息。
userid.null=用户名不能为空!-资源 |
在验证方法中,可以通过super.getText()方法来取得资源文件中的错误信息。
super.addFieldError("userid", super.getText("userid.null")); |
3.7、Struts2 + Spring联合开发(重点)
在Struts2中,如果想使用SSH联合开发,必须配置Struts2 + Spring的支持。
加入Struts2时,必须选择加入与Spring结合的插件包
还要将加入的冲突包删除。
同时在src下建立struts.properties,加入以下配置
Struts2.1后可以不需要再手工加入此配置,插件包中会自动加入。
在web.xml中加入以下配置,以便读取Spring配置文件
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> |
启动测试后,可以发现Struts2已经可以结合Spring开发了。
下面完成添加操作。
<center> <a href="pages/back/news!insertPre.action">添加新闻</a> <br/> <a href="pages/back/news!list.action">新闻列表</a> <br/> </center> |
这里的!insertPre和!list分别表示要调用的分发方法,Struts2中分发通过 !来完成分隔。 |
编写Action
public class NewsAction extends ActionSupport {
private INewsService service;
private List<NewsType> allType;
public String insertPre() throws Exception { allType = service.insertPre();
return "insert"; } |
这里通过Struts2的特性将allType自动设置到request范围内 |
配置这个Action。
先在spring中配置
<bean id="newsAction" class="cn.mldn.action.NewsAction"> <property name="service"> <ref bean="newsServiceImpl" /> </property> </bean> |
这里的id可以任意定义。 |
在struts.xml中也要配置。
<package name="back" namespace="/pages/back" extends="struts-default"> <action name="news" class="newsAction"> <result name="insert">/pages/back/news_insert.jsp</result> <result name="list">/pages/back/news_list.jsp</result> </action> </package> |
这里注意,action的class值必须与定义的<bean>的id相同。 |
实际上Struts2还可以使用Annotation来声明Action类。
@Controller public class NewsAction extends ActionSupport {
private INewsService service;
@Resource(name="newsServiceImpl") public void setService(INewsService service) { this.service = service; } |
@Controller的作用和@Service功能相同,都表示这是一个<bean>,id为类名首字母小写。 |
注意,要在applicationContext-hibernate.xml中将Action的包加入到annotation的检测范围内。
<context:component-scan base-package="cn.mldn.dao.impl,cn.mldn.service.impl,cn.mldn.action"></context:component-scan> |
在列出所有类型选项时,可以直接使用s:select来完成下拉列表
新闻类型: <s:select name="news.newsType.tid" list="#request.allType" listKey="tid" listValue="tname"></s:select> |
list表示要列表的集合,使用OGNL语法来完成,语法格式为: #属性范围.属性名 listKey表示作为value的属性名 listValue表示显示的属性名 headerKey和headerValue可以作为默认选项加入到下拉列表中 |