有关Hibernate的知识大部分都已经温习完毕,今天开始转向Struts的温习工作了
Servlet的演变:在常规的 JSP,Servlet,JavaBean三层结构中,JSP实现View的功能,Servlet实现Controller的功能,JavaBean实现Model的实现。
在Struts中,将常规情况下的Servlet拆分与ActionServlet、FormBean、ActionBean三个部分。ActionServlet配合Struts-config.xml,专职完成页面导航,而不再负责具体的数据获取与相应逻辑,这两部分功能由FormBean和ActionBean来完成。
Struts优缺点
优点:
Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者能更深入的了解其内部实现机制。
除此之外,Struts的优点主要集中体现在两个方面:Taglib和页面导航。Taglib是Struts的标记库,灵活动用,能大大提高开发效率。另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。
关于页面导航,我认为那将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
缺点:
Taglib是Struts的一大优势,但对于初学者而言,却需要一个持续学习的过程,甚至还会打乱你网页编写的习惯,但是,当你习惯了它时,你会觉得它真的很棒。
Struts将MVC的Controller一分为三,在获得结构更加清晰的同时,也增加了系统的复杂度。
Struts从产生到现在还不到半年,但已逐步越来越多运用于商业软件。虽然它现在还有不少缺点,但它是一种非常优秀的J2EE MVC实现方式,如果你的系统准备采用J2EE MVC架构,那么,不妨考虑一下Struts。
Struts实施经验:
1、基于Struts架构的项目开发,首先需要有一个很好的整体规划,整个系统中包括哪几个模块,每个模块各需要多少FormBean和ActionBean等,而且最好有专人负责Struts-config.xml的管理。开发基于Struts的项目的难点在于配置管理,尤其是对Struts-config.xml的管理
2、如果你的项目非常紧,并且项目组中又没有富有经验的Struts开发人员,建议不要冒然采用Struts。Struts的掌握需要一个过程,对于一个熟练的JSP程序员,自学大概需要半个月左右的时间。如果结合titls,则需要更长的时间
3、如果你在网页中大量运用taglib,那么你的美工将做出部分牺牲。当你结合Tiles,功能增强的同时,这种牺牲尤为明显。当然,你对功能和美观的取舍由你自己决定
4、Taglib是一个好东西,但灵活运用它却需要一个过程,如果你不想在Taglib上花太多的时间,那么只需理解与FORM有关的几个标记,其它的标记就放着吧,以后再看,先去研究ActionServlet和Struts-config.xml,你会觉得很有成就感
5、Struts是否只适合于大型项目呢?No!Struts适合于各种大小的项目,当然,对于大型项目,它所体现出来的优势更加明显。
解压struts1.3.10的ZIP包,将struts-1.3.10\apps\struts-blank-1.3.10.war解压,参考这个Struts的官方示例,在MyEclipse8.6中新建一个WEB项目,将struts-1.3.10\apps\struts-blank-1.3.10\WEB-INF\lib下的所有JAR包(除了struts-taglib-1.3.10.jar和struts-tiles-1.3.10.jar)拷贝到WEB工程中,
将struts-1.3.10\apps\struts-blank-1.3.10\WEB-INF下的三个XML文件拷贝的项目的WEB-INF下
当然这三个中,struts-config.xml是Struts必须的,至于struts-validator.xml由于这里要做一个登录,所以验证需要用上,当然既然是验证就需要有验证规则,还需要在同一目录添加struts-1.3.10\src\core\src\main\resources\org\apache\struts\validator
下的validator-rules.xml,web.xml毋庸置疑是WEB工程中必须的,引用struts-blank示例中的web.xml由于是配置好的,所以就直接拿来用了
对上面的这几简单的操作在Struts1.3.10之前版本来说呢,你的项目很快就能运行并且使用ActionForm和 Action,以前的版本只需要下面8个jar就可以
由于struts1.3.10中没有了struts.jar,而struts-blank中的lib下的jar包核心包为struts-core-1.3.10.jar
实际操作证明struts1.3.1项目除了必须的8个包之外,还需要一个struts-extras-1.3.10.jar,最终必须包为9个
下面看具体的类了
UserService.java
package com.javacrazyer.service;
public class UserService {
public boolean validate(String loginname, String password){
if("test".equals(loginname) && "test".equals(password)){
return true;
}else{
return false;
}
}
}
LoginForm.java
package com.javacrazyer.web.formbean;
import org.apache.struts.validator.ValidatorActionForm;
/**
* 用来收集客户端提交数据.
* 要收集数据的属性的名一定要跟请求参数名相同
*
*/
public class LoginForm extends ValidatorActionForm {
private static final long serialVersionUID = 6619272689058619128L;
private String loginname;
private String pwd;
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
ActionForm类:自动收集客户端提交的数据,并转换相应的数据(基本数据类型或字符串)
每一个FormBean 都必须继承ActionForm类,FormBean是对页面请求的封装。即把HTTP request 封装在一个对象中,需要说明的一点就是多个HTTP request可以共用一个FormBean,便于维护和重用。
FormBean的产生是为了提供数据给ActionBean,在ActionBean中可以取得FormBean中封装的数据,经相应的逻辑处理后,调用业务方法完成相应业务要求。
LoginAction.java
package com.javacrazyer.web.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.javacrazyer.service.UserService;
import com.javacrazyer.web.formbean.LoginForm;
/**
* 业务控制器:控制业务处理的流程
*
*/
public class LoginAction extends Action {
//具体业务流程处理方法,由Struts框架回调
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//取数据
LoginForm loginForm = (LoginForm)form;
String loginname = loginForm.getLoginname();
String pwd = loginForm.getPwd();
//调用业务逻辑
UserService service = new UserService();
boolean flag = service.validate(loginname, pwd);
//跳转
if(flag){
//成功
return mapping.findForward("succ");
}else{
//失败
request.setAttribute("errorMsg", "你输入的用户名或密码有误,请返回,重新登录!!!");
return mapping.findForward("failure");
}
}
}
Action类:针对指定请求路径进行具体业务流程处理的类。业务控制器。
src/msg.properties(这个内容也是复制struts-blank示例中的,后经过修改如下)
errors.required={0}\u662F\u5FC5\u987B\u7684.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0}\u8981\u662F\u5408\u6CD5\u7684.
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.
errors.float={0} must be a float.
errors.double={0} must be a double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is an invalid credit card number.
errors.email={0} is an invalid e-mail address.
MyForm.LoginName=\u767B\u5F55\u540D
MyForm.PassWord=\u5BC6\u7801
WEB-INF/struts-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<!-- ================================================ Form Bean Definitions -->
<!-- name给该FormBean指定一个唯一标识名,type指定对应的类 -->
<form-beans>
<form-bean name="loginForm" type="com.javacrazyer.web.formbean.LoginForm"/>
</form-beans>
<!-- =========================================== Action Mapping Definitions -->
<!-- 一个Action元素对应一个请求路径,
Action元素的基本配置:
path:指定该Action要处理的请求路径,必须以/开头,代表web应用的根路径。
name:指定该Action类需要使用的FormBean对象。
type:指定Action类的全限定名.
scope:可选值session,request.用来指定本Action要使用的FormBean对象应该存储在哪个范围内。默认值为session
validate:指定是否要回调ActionForm中的validate()方法对表单数据进行验证。默认true.
子元素forward的配置:
name: 指定本跳转路径的逻辑名。
path: 指定本跳转路径的目标路径,必须以/开头。
redirect:指定是否要采用重定向。默认值false(表示使用请求分派)。
-->
<action-mappings>
<action path="/login" name="loginForm" type="com.javacrazyer.web.action.LoginAction" validate="true"
input="/index.jsp">
<forward name="succ" path="/login_success.jsp"/>
<forward name="failure" path="/login_failure.jsp"/>
</action>
</action-mappings>
<!-- 配置验证信息插件类,指定paramerter值为msg,也即资源文件开头是msg -->
<message-resources parameter="msg" />
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<!-- 配置验证需要的验证配置文件 -->
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"><!--
<!-- 在web.xml注册struts框架的前端控制器:ActionServlet-->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Struts的核心是Controller,即ActionServlet,而ActionServlet的核心就是Struts-config.xml,Struts-config.xml集中了所有页面的导航定义。对于大型的WEB项目,通过此配置文件即可迅速把握其脉络,这不管是对于前期的开发,还是后期的维护或升级都是大有裨益的。掌握Struts-config.xml是掌握Struts的关键所在。
validation.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
<!--
This is a minimal Validator form file with a couple of examples.
-->
<global>
<!-- An example global constant
<constant>
<constant-name>postalCode</constant-name>
<constant-value>^\d{5}\d*$</constant-value>
</constant>
end example-->
</global>
<!-- An example formset for another locale -->
<formset >
<!-- name:这里的name值要与struts-config中配置的path的值一样,这样的话登录页面提交的 action正好是/login.do
就正好匹配为登录页面做验证了,如果其他表单页面的表单action也是/login.do并且对应的ActionForm的值也和下面的对应,
同样也为这个页面做验证 -->
<form name="/login">
<!-- property:对应ActionForm的属性; depends:指定验证规则,例如:required、maxlength等; -->
<field
property="loginname"
depends="required">
<!-- 其中<arg0 key="MyForm.LoginName" />中的key跟资源文件中的键对应。 -->
<arg key="MyForm.LoginName"/>
</field>
<field
property="pwd"
depends="required,mask">
<arg key="MyForm.PassWord"/>
<!-- 对密码输入框输入值,进行如下正则表达式规则的验证:必须是字母开头的 -->
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z][a-zA-Z0-9]*$</var-value>
</var>
</field>
</form>
</formset>
</form-validation>
login.jsp
<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Struts第一个应用:登录验证</title>
</head>
<body>
<h3>Struts第一个应用:登录验证</h3><hr/>
<ul style="color: red;">
<html:messages id="msg">
<li><bean:write name="msg"/></li>
</html:messages>
</ul>
<form id="myForm" name="loginForm" action="login.do" method="post">
<table border="1" width="600px">
<tr>
<td>登录名</td>
<td><input type="text" name="loginname" value="${param.loginname}"/>
</td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="pwd" value="${param.pwd}"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</td>
</tr>
</table>
</form>
</body>
</html>
此JSP页面不同于普通的JSP页,因为它大量运用了taglib,这些taglib对初学者而言,可能难于掌握,可这却是Struts的精华之一。灵活运用,将大大提高开发效率。
login_failure.jsp
<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录失败</title>
</head>
<body>
<h3> 登录失败</h3><hr/>
<h2 style="color:red">可能的原因是:
${errorMsg}
</h2>
</body>
</html>
login_success.jsp
<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h3>登录成功</h3><hr/>
<h2>欢迎:${param.loginname}登录!</h2>
</body>
</html>
部署项目,运行起来,如果登录成功
如果没有输入用户名和密码
如果没输入密码
如果没输入用户名
如果用户名密码不正确
最后就本节中用到的validator框架做下总结
1. 在struts应用中使用Validator框架的步骤
1) 在/WEB-INF/下添加两个配置文件
a) validator-rules.xml 定义一些通用的验证规则。
b) validation.xml 开发人员在这个文件中配置所需要验证的表单和字段及相应的验证规则
2) 在struts的配置文件中以插件的方式添加validator框架
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
3) 需要验证的ActionForm必须继承ValidatorForm或ValidatorActionForm,且不要重写validate()方法。
在struts配置文件对应的<action>元素上validate属性的值要为true(默认值)
4) 在validation.xml中配置验证规则。
<form name="loginForm">
<!-- property指定要验证的属性名,depends指定要使用的验证规则列表
<field property="loginname" depends="required">
<!-- 用来给验证失败信息的占位符给具体值,分别用arg0,arg1,arg2,arg3来对应顺序 -->
<arg0 key="loginForm.username"/>
</field>
<field property="pwd"
depends="required,mask">
<arg key="loginForm.pwd"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z][a-zA-Z0-9]*$</var-value>
</var>
</field>
</form>