---------------------------->struts1.x 基础
(1)
什么是struts:
是采用MVC模式的web application的Framework.
什么是MVC:
最常见的思考模式,在这个模式里,将web application分为:处理流程的Controller,处理业务(bussiness logic)的Model,和显示结果的View.
什么是Framework:
是一种为开发应用程序而设计的框架.利用框架,可以提高应用程序的开发质量和效率,但在使用它之前,须了解框架的原理,及方法.
描述Struts体系结构?对应各个部分的开发工作主要包括哪些?
Struts 是MVC的一种实现,
1)模型(Model)
2)视图(View)
视图主要由JSP建立,struts包含扩展自定义标签库(TagLib),可以简化创建完全国际化用户界面的过程。目前的标签库包括:Bean Tags、HTML tags、Logic Tags、Nested Tags 以及Template Tags等。
3)控制器(Controller)
1.在struts中,基本的控制器组件是ActionServlet类中的实例servelt,实际使用的servlet在配置文件中由一组映射(由ActionMapping类进行描述)进行定义。
2.对于业务逻辑的操作则主要由Action、ActionMapping、ActionForward这几个组件协调完成的,其中Action扮演了真正的业务逻辑的实现者,ActionMapping与ActionForward则指定了不同业务逻辑或流程的运行方向。
3.struts-config.xml 文件配置控制器。
(2)
action-mappings的结构:
<action-mappings>
<action
input="/userLogin.jsp"
name="userLoginForm"
path="/userLogin"
scope="request"
type="com.yourcompany.struts.action.UserLoginAction"
validate="false">
<forward name="success" path="/userLoginSuccess.jsp" />
<forward name="failure" path="/userLogin.jsp" />
</action>
</action-mappings>
form-beans的结构:
<form-beans >
<form-bean name="userLoginForm" type="com.yourcompany.struts.form.UserLoginForm" />
</form-beans>
(3)
struts的工作流程:
1.在web应用启动时就会加载初始化ActionServlet,ActionServlet从struts-config.xml文件中读取配置信息;
2.当ActionServlet接收到一个客户请求时,查找和用户请求匹配的ActionMapping实例;
3.把客户提交的表单数据保存到相应的ActionForm对象中;
4.根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法;若返回ActuibErrors==null, 就表示表单验证成功; 否则跳转到input定义的页面.
5.验证成功,跳转到相应的Action,执行其中的execute()方法.
6.execute()方法返回一个ActionForward对象,根据配置文件,跳转到相应的JSP页面.
(4)
ActionForm的操作:
4.1
验证方法:
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
{
ActionErrors errors=new ActionErrors();
if(userName.length()==0)
{
ActionError error=new ActionError("u.error"); //资源包中的信息
errors.add("userName",error);
}
...
return errors;
}
4.2对actionForm的改变一:
validator的应用:代替手写的validate():
validator的运行原理:
其实就是与validate一样,只是省略了它的相关代码:若验证出错,会产生一个ActionError,并以errors.验证类型(如:errors.required)存放到ActionErrors中,以request scope的形式.
*1,配置文件中,添加相应的插件代码
先到struts-configj.xml中添加相应的代码:
将validate="true",并填input的值-->再插入如下的代码:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml">
</plug-in>
------>若用ECLIPSE创建Struts,validator-rules.xml已自动导入,我们只需创建validation.xml.
*2,创建validation.xml
<?xml version="1.0"?>
<!DOCUMENT....>
<form-validation>
<formset>
<form name="formbean的名">
<field property="要验证的field" depends="如:required,mask,email">
<arg0 key="userNameRequired"/> //若带参数
<var>
<var-name>mask</var-name>
<var-value>^[A-Za-z0-9]{n,}$</var-value>
</var>
</field>
</form>
</formset>
</form-validation>
*3,修改formbean中的父类:ActionForm -->ValidatorForm
*4,在资源文件中,添加验证类型的错误信息提示:如:
errors.required=the username can't be none
*5,在返回错误信息页面,用<html:errors/>返回错误信息.
*6, 同时,不能在formbean中定义方法validate()--important
4.3对actionForm的改变二:
利用DynaActionForm动态生成一个ActionForm(不用手写form):
*1
在<form-bean>中,type="org.apache.struts.action.DynaActionForm";
并且在<form-bean>中,添加表单中相应的列的设置,如:
<form-property name="jusername" type="java.lang.String" initial="wjaosn" />.若有多个属性,则添加多个
*2
不用写传统的ActionForm.
*3
在DynaActionForm中,则无法用到传统ActionForm中的reset(),validate()方法,但可以用validator的验证方法去代替validate()方法.
(5)
ACTION的操作
5.1
Action的结构:
public class UserAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
............
return mapping.findForward("sucess");
}
}
5.2
利用DispatchAction进行不同提交,进行不同处理,跳转到不同页面.
*1
在<action>中添加属性parameter="值1"-->此值,也要在submit按钮中设置为其属性,否则出错.如:
parameter="action"..
<html:submit property="action">
<bean:message key="button"/>
</html:submit>
*2
在ActionClass中,
要继承的类是DispatchAction,不是原来的Action;
不能有原来的execute方法,否则DispatchAction失效;
自定义方法.其方法名与submit按钮的value的值一样;方法的参数,返回值与execute一样.
(6)
资源包的操作:
资源包可以含参数,如:label.welcome=Welcome back {0} {1}! 最多可放4个参数.
定义的位置:
可在web.xml;
也可在struts-config.xml中进行设置,如下:
<message-resources parameter="绝对路径+文件名"/>
如:<message-resources parameter="resources.application"/>
struts的国际化支持
在struts中,浏览器传送过来的accept-language会被存放于:以org.apache.struts.action.LOCALE为key,以Locale对象的方式存放在session中.在struts中,会自动根据存放于session中的这个key,来切换资源包.
选择过程:
1Struts并不是单纯去找application.properties文件,而是首先找到application,
2然后加上下划线"_",然后再加上localeKey(如zh,en),
3然后再加上.properties($filename_$locale.properties)。
4如果这里没有找到和locale对应的资源文件,Struts就使用application.properties,
5如果这个文件也没找到,Struts会报告错误。
(7)
标签使用:
7.1
<bean:message>
如果想从MessageResource文件中取出与key相对应的信息输出到JSP,就必须使用<bean:message>.
如:
MessageResource中: status=这次实操,{0}已做{1}了!
在JSP中:
<%
String who="jason";
String m="成功";
%>
<bean:message key="status" arg0="<%=who%>" arg1="<%=m%>"/><br>
7.2
bean:write:
如何将ActionClass中的信息传递到JSP中.
在ActionClass中,可以利用request.setAttribute("组件",值)进行设置.
在JSP页面,可以<bean:write name="组件" / >进行获取.
7.3
<html:errors>
此标签会将存放在scope=request中的string,ActionErrors对象的内容显示出来.
<html:errors property="userName"/>
7.4
<li>输出formbean中的属性循环</li>
<logic:iterate id="JB" name="userLoginForm" property="addr" indexId="Jindex2" scope="request">
<li>
<bean:write name="JB"/>--<bean:write name="Jindex2"/>
</li>
</logic:iterate>
</ul>
各属性说明:
id:定义一个名,作为循环输出内容的名.(可用于bean:write的输出)
name:指定某一对象,或某一bean.
property:指定BEAN要进行循环的属性.(此属性可为数组,arraylist,vector等.)
scope:作用域.若不指定,会从系统会自动从作用域page搜索到作用域application.
offset:循环的开始位置(0:第一个)
length:循环的次数
indexId:循环过程的索引名.(可用于bean:write的输出索引)
为什么要使用Struts?
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。提高开发的效率,质量.
---------------------------->struts2.0 基础
(1)
1.
拦截器:
拦截是AOP的一种实现策略。即是动态拦截Action,在action执行之前(struts只能在其执行前,AOP可以在执行的前后)添加相应的代码,逻辑.
拦截器链就是将拦截器按一定的顺序联结成一条链。
执行流程:
当请求到达Struts 2的FilterDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器,最后才到达action.
2.在struts.xml文件中定义拦截器,拦截器栈:
<interceptors>
<!-- 定义拦截器 -->
<interceptor name="拦截器名" class="拦截器实现类"/>
<!-- 定义拦截器栈 -->
<interceptor-stack name="拦截器栈名">
<interceptor-ref name="拦截器一"/>
<interceptor-ref name="拦截器二"/>
</interceptor-stack>
</interceptors>
<action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result> <!-- 使用拦截器,一般配置在result之后, -->
<interceptor-ref name="defaultStack"/> <!-- 引用系统默认的拦截器 -->
<interceptor-ref name="拦截器名或拦截器栈名"/>
</action>
此处需要注意的是,如果为Action指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,所以上面配置文件中手动引入了默认拦截器。
3.自定义拦截器:
所有的Struts 2的拦截器都直接或间接实现接口Interceptor。该接口提供了三个方法:
void init();void destroy();
String intercept(ActionInvocation invocation) throws Exception;
该方法是用户需要实现的拦截动作。该方法会返回一个字符串作为逻辑视图。
或
除此之外,继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor是更简单的一种实现拦截器类的方式.因为此类提供了init()和destroy()方法的空实现,这样我们只需要实现intercept方法。
或
Struts2提供MethodFilterInterceptor类,该类是AbstractInerceptor的子类,有两个方法 :
setExcludeMethods:排除需要过滤的方法(这里的方法,是指相应的Action中的方法);
setIncludeMethods:设置需要过滤的方法;
如果一个方法同时在excludeMethods和includeMethods中出现,则会被拦截.
如:
<interceptor-ref name="myFilter">
<param name="excludeMethods">execute,view,edit</param>
<param name="includeMethods">add,list</param>
</interceptor-ref>
在拦截器中可以获取这些东西:
public String intercept(ActionInvocation invocation) throws Exception
{
ActionContext ac=invocation.getInvocationContext();
Object action=invocation.getAction();
String actionName=ac.getName();
Map map=ac.getParameters();
.......
可以获取request,session(ac.getSession)
}
最后调用:return invocation.invoke();进入下一个拦截器,或进入Action.
4.
ActionContext 与 ServeltActionContext
4.1
ActionContext是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放放的是Action在执行时需要用到的对象
如:
获取HttpSession:
Map session = ActionContext.getContext().getSession();
在Action中取得request请求参数"username"的值:
ActionContext context = ActionContext.getContext();
Map params = context.getParameters();
String username = (String) params.get("username");
4.2
ServletActionContext
这个类直接继承了上面介绍的ActionContext,它可以取得的对象有:
1, javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
2, javax.servlet.http.HttpServletResponse;:HTTPservlet相应对象
3, javax.servlet.ServletContext:Servlet 上下文信息
4, javax.servlet.ServletConfig:Servlet配置对象
5, javax.servlet.jsp.PageContext:Http页面上下文
虽然 ActionContext 的 getSession 返回的不是 HttpSession 对象,而是Map对象.但 Struts 2 的系列拦截 器会负责该 Session 和 HttpSession 之间的转换。
5 valueStack:
当Action设置了某个属性值后,Struts 2将这些属性值全部封装在一个叫做struts.valueStack 的请
求属性里。从数据结构上来看,ValueStack 有点类似于Map结构,但它比Map结构更加强大。可以通过OGNL表达式非常方便地访问该对象封装的信息。
如下:
<%
//获取封装输出信息的 ValueStack 对象
ValueStack vs = (ValueStack)request.getAttribute("struts.valueStack");
//调用 ValueStack 的 fineValue 方法获取 Action 中的 books 属性值
String[] books = (String[])vs.findValue("books"); //因为上面定义了属性books
//迭代输出全部图书信息
for (String book : books)
{
%>
<tr>
<td>书名:</td>
<td><%=book%></td>
</tr>
<%}%>
另一种方式是:
class Book
{
private String title;
private int price;
private String comment;
getter,setter....
}
在Action中添加:(无须放入request,或session):
list=new ArrayList<String>();
list.add("jason");
list.add("hwj");
Book b1=new Book();
b1.setTitle("java");
b1.setPrice(20);
b1.setComment("for java");
Book b2=new Book();
b2.setTitle("jsp");
b2.setPrice(30);
b2.setComment("for jsp");
booklist=new ArrayList<Book>();
booklist.add(b1);
booklist.add(b2);
在页面用<s:iterator>输出:
s:iterator输出list:
<s:iterator value="list">
<s:property />
</s:iterator>
<br/>
<s:iterator value="booklist">
书名:<s:property value="title"/>--价格:<s:property value="price"/>--注释:<s:property value="comment"/><br/>
</s:iterator>
有过滤效果:
<s:iterator value="booklist.{?#this.price>20}">
书名:<s:property value="title"/>--价格:<s:property value="price"/><br/>
</s:iterator>
<s:iterator value="booklist.{?#this.comment=='for java'}">
comment内容是for java的书名是:<s:property value="title"/>
</s:iterator>
<br/>
6.国际化:
输出国际化信息:
Struts 2 提供了如下两种方式来输出国际化信息:
<s:text name="messageKey"/>:使用 s:text 标签来输出国际化信息。
<s:property value="%{getText("messageKey")}"/>:使用表达式方式输出国际化信息。
7.数据验证:
方式一:
继承 ActionSupport
ActionSupport 类是一个工具类,它已经实现了 Action 接口。除此之外,它还实现了
Validateable 接口,只须重写Validatable 接口中定义的validate()方法,即可实现:
执行系统的execute 方法之前执行,执行此validate()方法,实现数据校验功能,如果执行该方法之后,Action 类的fieldErrors 中已经包含了数据校验错误,请求将被转发到input逻辑视图处。
如下:
public void validate()
{
//如果用户名为空,或者为空字符串
if (getUsername() == null || getUsername().trim().equals(""))
{
//添加校验错误提示,使用 getText 方法来使提示信息国际化
addFieldError("username", getText("user.required"));
}
if (getPassword() == null || getPassword().trim().equals(""))
{
addFieldError("password", getText("pass.required"));
}
}
修改struts.xml,添加input: <result name="input">/login.jsp</result>
方式二:
使用 Struts 2 的校验框架
1.
定义校验规则文件,该文件的命名应该遵守如下规则:
ActionName-validation.xml:其中 ActionName 就是需要校验的 Action 的类名。如:
"jLogin-validation.xml",且该文件应该与Action类的class文件位于同一个路径下。
2.
此文件定义如下:
<validators>
<field name="username">
<field-validator type="requiredstring">
<message key="user.required"/>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<message key="pass.required"/>
</field-validator>
</field>
</validators>
3.
struts.xml定义input.
8.
struts.properties 配置文件
Struts 2 框架有两个核心配置文件,其中 struts.xml 文件主要负责管理应用中的 Action
映射,以及该 Action 包含的 Result 定义等。除此之外,Struts 2 框架还包含一个
struts.properties 文件,该文件定义了 Struts 2 框架的大量属性,开发者可以通过改变这些属
性来满足应用的需求。
struts.properties 文件是一个标准的Properties文件,该文件包含了系列的 key-value 对
象,每个 key 就是一个 Struts 2 属性,该 key 对应的value就是一个 Struts 2 属性值。
struts.properties 文件通常放在 Web 应用的 WEB-INF/classes 路径下(即与struts.xml一样的位
置)。
如:
struts.action.extension=bbscs
struts.ui.theme=simple
struts.locale=zh_CN
struts.i18n.encoding=UTF-8
struts.objectFactory=spring
struts.objectFactory.spring.autoWire=name
struts.locale:指定 Web 应用的默认 Locale。
struts.i18n.encoding:指定 Web 应用的默认编码集。该属性对于处理中文请求参数
非常有用,对于获取中文请求参数值,应该将该属性值设置为 GBK 或者 GB2312。
struts.objectFactory
指定Struts 2默认的ObjectFactory Bean,该属性默认值是spring.
struts.objectFactory.spring.autoWire
指定Spring框架的自动装配模式, 该属性的默认值是name, 即默认根据Bean的name属性自动装配.
struts.custom.i18n.resources
该属性指定Struts 2应用所需要的国际化资源文件,如果有多份国际化资源文件,则多个资源文件的文件名以英文逗号(,)隔开.
9.标签:
9.1 s:url的用法:
URL地址标签,<s:url>用于生成一个URL地址,可以通过URL标签指定的<s:param>子元素向URL地址
发送请求参数.
1.
普通的链接,用value属性:
<a href="<s:url value="Login_input.jsp"/>">Sign On</a>
2.
链接到action:
<a href="<s:url action="Register"/>">Register</a>
3.
分开写,有id来指定名称:
<s:url action="input" id="regurl" namespace="/reg"></s:url>
<a href="${regurl}"><s:text name="reg.title"/></a>
4.
带参数,用<s:param name>:
<s:url id="url" action="HelloWorld">
<s:param name="request_locale">es</s:param>
</s:url>
9.2 set标签,用于将某个值放入指定的范围内。例如application,session等。
<s:set name="user" value="userName" scope=”request”/>
将user值放入request范围内。
----------------------------------->struts1.x与struts2.0区别
struts1.x与struts2.0区别:
struts2与struts1相比,有了很多改进.它是在WebWork基础发展起来.从某种程序上讲,struts2没有继承struts1的血统,而是继承了WebWork的血统,是WebWork的升级.
(1)
Action方面:
Struts1要求Action类继承一个抽象基类Action.Struts1的一个普遍问题是使用抽象类编程而不是接口。
Struts 2 Action类可以实现一个Action接口,也可实现其他接口,同时,Struts2提供一个ActionSupport基类去实现常用的接口。Action接口不是必须的,任何包含有execute()的POJO对象都可以用作Struts2的Action对象。
(2)
Servlet 依赖:
Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
Struts 2 Action不依赖于容器.单元测试更容易
(3)
捕获输入:
Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类ActionForm。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的类捕获输入。
Struts 2直接使用Action属性作为输入属性.避免要创建actionForm.
(4)
表达式语言:
Struts1 整合了JSTL,因此使用JSTL EL。
Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--(OGNL).
struts1.x(用s1表示)与struts2.0(s2)的详细对比:
1)
在web.xml上:
s1:
是配置在servlet中的,其类是ActionServlet,其匹配是:<url-pattern>*.do</url-pattern>(后辍do)
s2:
是配置在filter中的,其类是FilterDispatcher,其匹配是:<url-pattern>/*</url-pattern>(后辍action,且可自定义)
2)
在配置文件上:
S1:
配置文件是struts-config.xml,其结构是<form-beans>,<action-mappings>,<message-resources>.
每个<action>都放于<action-mappings>中,须设置path,name,type,validate,input,parameter等.跳转是用:<forward name="sucess" path="">.
S2:
配置文件是struts.xml,其结构是<package>中,可以继承另一package,可以自定义+加入拦截器,
每个<action>都放于<package>中,须设置name,class.跳转是用:<result name="sucess">...</result>.
3)
在Action上:
S1:
用actionForm来获取页面表单数据,在ACTION中调用;须继承基类Action,execute()带参数;跳转方式:reutrn mapping.findForward("success");
S2:
将actionForm和action合在一起,用action的属性表示页面的属性,通过拦截器进行获取值.
只要有execute()方法的POJO类,都可作为其action.
跳转方式: reutrn SUCCESS;或reutrn "search";
4)
标签上:
S1:
前缀是html.如<html:html locale="true">,<html:text property="userid"/>,用property设置field名
S2:
前缀是s.如<s:form>,<s:textfield name="userid"/>,用name设置field名.