新手笔记,请大神们指点!
阿_彪
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
谢谢 ,希望大神们多提提宝贵意见!
|