新手笔记,请大神们指点!

阿_彪 2013-08-03
day30


1:Action如何获取请求参数
之前都是通过ActiontContext.getcontext()来获取(request,context,application)域,返回一个map集合,从而根据key获取value的方法!
1.1属性驱动
属性驱动方式来封装请求参数,这需要Action中给出属性,并且属性名(字段名必须与表单项一致),如(javaBean)一样,但只需提供setXxx()方法即可。
JSP如下:
  用户名:<input type="text" name="username"/><br/>
  密    码:<input type="password" name="password"/><br/>
理解
我们在jsp访问action时,特定先经过web.xml中的过滤器,web.xml再根据src下的struts.xml来分配Action对象。

就是struts.xml配置中,继承的 一个父类,(也有拦截器),除了拦截一些信息之外(校验),还会去查看你Action中是否有与表单对应的name属性(setXxx),如果有,就会把表单的值直接给你赋上去!

小结:在Action执行之前,会先出执行一系列的拦截器,是其中一个为params名字的拦截负责给你赋值!
步骤:
1:创建jsp页面
2:在web中配置过滤器(....一个大玩意)
3:在src下创建struts.xml文件
4:建立一个包---类
5:该类要继承ActionSupport
6:创建与表单相应的属性以及setXxx方法
[7:重写execute方法|以及其他判断]

1.2模型驱动-------->OGNL
所谓模型驱动,就是在jsp表单中,name的值为对象(user).字段(username);拦截器会对象到Action中查找相应的对象(Action中的属性)如下:
Action{
private User user;//找到这个属性,再找相应的setXxx()方法
private void setUser(User user){
this.user=user;
}
}
再通过User对象找到user中的属性,从而就赋值了。


小结:
1:User对象中的属性必须要符合javaBean(set和get)
2:拦截器只会给jsp创建一次User对象,第二次直接调用set方法赋值!
步骤:
1:创建jsp页面
2:在web中配置过滤器(....一个大玩意)
3:在src下创建struts.xml文件
4:建立一个包--->(User对象类,Action类)
5:Action继承ActionSupport
6:User创建与表单相应的属性值(javaBean)
7:在Action对象中创建属性为User对象(也可是Map集合)(字段),并提供setXxx方法
[8:重写execute方法|以及其他判断]

1.3:模型驱动-------->ModelDriven接口

概念:ModelDriven与OGNL方式很相似,都属于驱动的方式,表单的方式与属性驱动很象,不需要使用OGNL表达式
<form action="<c:url value='/loginAction.action'/>" method="post">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
</form>

步骤:
1:创建jsp页面
2:在web中配置过滤器(....一个大玩意)
3:在src下创建struts.xml文件
4:建立一个包--->(User对象类,Action类)
5:Action继承ActionSupport 实现ModelDriven接口
6:创建User对象,属性与表单必须一致!并提供set与get方法(javaBean)
7:在Action中创建user字段,
8:实现ModelDriven<User>的getModel()方法,把user返回。 ---A点
9:在Action定义  表单请求的方法

public class UserAction extends ActionSupport implements ModelDriven<User> {
private User user = new User()[必须手动初始化];
@Override
public User getModel() {
return user;
}
public String login() {
System.out.println(user);
return NONE;
}
}

小结:
1:拦截拿到表单项,它会检查Action对象是否实现了ModelDriven接口,
实现了
调用getModel()方法,获取User对象,如果为null,那么则不封装!
没有实现
..再判断你是为属性模型(因为你表单项只写一username,拦截应该能缩小范围,知道OGNL表达式是对象.字段的!),...
2:自定义异常错误信息
步骤:
1:在Action目录下创建ActionName.properties文件(与Action同名的properties文件)!
2:在该配置文件中如下配置
invalid.fieldvalue(固定的).属性名=错误信息!
例如:invalid.fieldvalue.person=无法将请求参数转换成Person类型!

小结:
1:properties文件名必须与Action类名一致!
2:[在input结果码对应页面中导入struts2标签库]
<%@ taglib prefix="s" uri="/struts-tags" %>
3:[使用fieldError来打印字段错误信息]
<s:fielderror/>
3:类型转换流程
页面表单---------->params拦截器------>conversionError拦截器-------->workflow拦截器------->Action请求处理方法
params拦截器:
获取请求参数,通过对应的类型转换器把请求参数转换成目标类型后,封装到Action中 (struts2自动的)
conversionError拦截器
当params出现了类型转换,struts没有定义的类型转换器(或)不能转换就会抛出异常信息(出错),而conversionErroe拦截器(记录器)会把错误信息保存到finedError中
workfolw拦截器
它是负责查看fieldError中是否存在错误信息。如果存在,那么将不继续向下执行过滤器(或执行Action的请求处理方法,而是跳转到input结束码),然后,那你么应该在struts.xml的<action>元素中配置<resul name='input'>,继续你就可指定一个错误页面来显示了。但是,如果一切都没有出错,这些都不会执行!就正常去执行jsp向Action发送的处理方法了!


4:输入校验
概念:在javaweb中我们使用serlvet来接收(业务员)  再把值分配给(开发人员(逻辑类))去执行校验!同样在struts中也提供了以下
三种方式可以校验:

4.1:代码公有校验
步骤:
1:配置struts环境
|--导入11个包
|--在web下加入过滤器class=org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|--在src下创建struts.xml文件ActionSupport
2:创建Action类,继承ActionSupport,重写 validate()方法  [还可以实现DodelDriven接口]
注:当validate会在execute方法之前执行,如果数据不符合你定义的规则,那么则会停止向下执行!
你就可以把错误信息使用以下来添加信息,

this.addActionError(anErrorMessage)//添加校验错误的信息

this.addActionMessage(aMessage)//添加成功信息

this.addFieldError(fieldName, errorMessage)//添加域错误


<s:actionerror/>显示错误信息
<s:actionmessage/>
<s:fielderror/>//


默认在源代码中,如好象execute方法它会返回一个input,那么则会去找input页面,你需要在struts.xml中
的<result>/index.jsp</result>属性给一个路径!

手动在本此方法头上使用注解来定义异常页面
@InputConfig(resultName="LoginError")//那么则会去struts.xml目录下找
<result name="LoginError">/index.jsp</result>属性给一个路径!

3:在Action类创建属性!
一般来说,都使用模型驱动-------->ModelDriven接口获取值!
注意:如果是User对象,必须要手动初始化!
4:重写execute()方法或根据请求参数来定义(处理)方法!;

4.2:私有校验
步骤:
1:配置struts环境
|--导入11个包
|--在web下加入过滤器class=org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|--在src下创建struts.xml文件ActionSupport
2:创建Action类,继承ActionSupport
3:在Action类创建属性!
一般来说,都使用模型驱动-------->ModelDriven接口获取值!
4:struts给我定义一个私有的校验规则:
|--以validateXxx()对应表单的处理方法
如:jsp:   /user_登录.action
如果为User对象,则需要手动初始化!

4.3:xml校验
步骤:
1:创建Action类,继承Validateable接口
2:创建struts.xml文件!
3:校验的文件名必须为:Xxx(Action类)-validation.xml
4:校验.xml文件必须与Action在同包下
5:校验文件的DTD(约束)
   在xwork-core-x.x.x.jar中找到xwork-validator-1.0.3.dtd,把内部的DTD,copy到校验.xml中
6:方便在MyEclipse中有提示信息,在Windows---->最底下一个,搜索xml,再找到XML Catalog,
点Add添加
Location:<%盘符路径%>struts2\struts-2.3.7\src\core\src\main\resources\struts-2.3.dtd
Key type:URI//类型
Key http://struts.apache.org/dtds/xwork-2.3.dtd//
7:

5:国际化
...

6:拦截器
概念:struts中的拦截器,与以前过滤器很类似,都具备着中断jsp请求的能力!
6.1路径
struts2中定义在很多拦截器,在struts2-core-2.3.7.jar包下struts-default.xml配置文件中!

6.2struts-default.xml配置三分类
<result-types> [我们在src下定义struts.xml继承了struts-default.xml,所以可以使用父包中定义的结果类型。]
....
<interceptors> [这是struts中定义的拦截器,不代表都会执行,需要手动引用!]
....
<interceptor-stack name="basicStack"> [这是拦截器栈]
....
<interceptor-stack name="defaultStack"> [这是默认拦截器栈,每个Action执行之前都会执行这个栈中引用的拦截器。]
....
<default-interceptor-ref name="defaultStack"/> [指定defaultStack为默认拦截器栈,这样才会在每个Action执行之前执行该栈中的拦截
器。]
6.3自定义拦截器
6.3.1概念:struts2为了提高扩展性,定义一个接口,把使用者把拦截器定义在Interceptor接口中
public interface Interceptor extends Serializable {
    void destroy [拦截器销毁之前被执行]();
    void init [拦截器创建之后被执行]();
    String intercept(ActionInvocation invocation) throws Exception; [每次拦截请求都会被执行。]
}

6.3.2步骤:
1:为了不必须去实现Interceptor所有方法,就选择继承AbstractInterceptor类
2:重写intercept方法
范例:
public class MyInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invaction) throws Exception {

System.out.println("MyInterceptor...");//定义相关拦截器

return invaction.invoke();//放行
}
}
6.3.3 注册拦截器1

<package name="s8" namespace="/" extends="struts-default">

<声明拦截器>
<interceptors>
<interceptor name="MyInterceptor" class="继承了AbstractInterceptor或实现Interceptor接口的子类对象路径classPathName" />
</interceptors>

<action name="huizhi">

<result>/index.jsp</result>
<result name="input">/login.jsp</result>

<interceptor-ref name="MyInterceptor(与外部声明的name值必须对应)" /> [引用拦截器,访问/huizhi路径--->再执行该Action时就会执行这个拦截器。]

<interceptor-ref name="defaultStack" /> [defaultStack就不用在声明了,因为package继承的struts-default包中已经声明过了。]

</action>
</package>

小结:
1:拦截器在package下声明,可以在多个action下引用!
2:如果自定义了拦截器,那么struts2默认拦截器就不会执行了(失效) [理解为:一个类,如果定义带参构造,那么默认无参就没有了],那么我们的好多输入校验就没戏了。所以需要引入默认的拦截,不需要声明,因为package是继承struts-defautl.xml!(子类继承父类,父类声明了,子类只需引用即可)
3:执行顺序:如果引入的父类中默认拦截器,那么则  顺序为: 父类拦截器------>子类拦截器!

////////////////////////////////////////////////////////////////////////

6.3.3 注册拦截器2

   上面的方式虽然可以注册拦截器,但比较麻烦。因为如果当前包中所有<action>都需要执行MyInterceptor拦截器,那么就需要在每个<action>元素中引入拦截器。其实还有另一种方式,就是为当前包指定默认拦截器栈!
    我们都知道,因为我们的包继承了struts-default包,所以默认的拦截器栈是defaultStack,但没有为<action>元素指定拦截器时,那么就会执行defaultStack拦截器栈。我们可以在<package>中声明一个拦截器栈,然后在去替换默认拦截器栈即可。
<package name="s8" namespace="/" extends="struts-default">

<interceptors>
<interceptor name="MyInterceptor" class="cn.itcast.interceptor.MyInterceptor" />[声明拦截器]

<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="MyInterceptor" />
</interceptor-stack> [声明拦截器栈]

</interceptors>


<default-interceptor-ref name="myStack" />[指定当前包的默认拦截器]

<action name="LoginAction [因为当前<action>没有指定拦截器,所以执行默认拦截器栈扣的拦截器。]">
<result>/index.jsp</result>
<result name="input">/login.jsp</result>
</action>

</package>
lvwenwen 2013-08-09
写得不错!
阿_彪 2013-08-12
谢谢  ,希望大神们多提提宝贵意见!
Global site tag (gtag.js) - Google Analytics