Struts2学习笔记

在前面我已经说过Struts2了,那么,还是有些东西遗漏了,虽然都是一些基础技术,和Struts2整体相比简直是太渺小了,不过知识都是慢慢积累的


认识新指令<include>


include : 
 为应用指定多个Struts配置文件
* 在大部分的应用里,随着应用的规模增加,系统中的Action的数量也会增大
 导致Struts.xml配置文件,变得相当臃肿,为了避免Struts.xml文件过于
 庞大,提高Struts.xml文件的可读性,我么可以将一个Struts.xml配置文件
 分解成多个配置文件,然后在Struts.xml文件文件中包含其他配置文件。


<struts>
<include file="struts-user.xml" />
</struts>
通过这样的方式,我么就可以将Struts2的Action按照模块添加在多个配置文件中




再次学习<package>及<action>标签


<package name="test">

*获取请求路径的URL,例如:http://localhost:8080/server/struts2/path1/path2/path3/test.action
*首先会去寻找namespace为/path1/path2/path3的package,如果存在这个package,则这个package中寻找
名字为test的action


*上面如过没找到就寻找namespace为/path1/path2/的package,如果存在这个package,则在这个package中
寻找为test的action


*上面如果还没找到就寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找
名字为test的action


*如果以上都没找到,那么最后就去默认的namespace的package下去找名字为test的action(默认的命名空间为空字符串"")
如果还找不到,那么页面提示找不到action



<action name="test">
<result>
*  如果没有指定class属性,默认是ActionSupport,而执行这个方法返回一个字符串常量SUCCESS
*  如果没有为action指定 指定action中的execute()方法
*  如果没有指定result的name属性,默认值为success
</result>
</action>
</package>






使用动态方法调用DMI,可以在URL中动态指定action执行哪个方法,URL地址如下
//http://localhost:8080/Struts2xuexi/user.action!add
   
//上面输入是错误的,这样就找不到对应的页面了


http://localhost:8080/Struts2xuexi/user!add
这样就行了,在使用DMI后面的user默认会带上.action的

   方法:action + ! + 方法名


   注意:
只要Action中有这个方法,并返回一个String类型就可以调用了


  Struts2.xml的配置


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

<action name="user" class="xx.oo.action.TestAction">
<result>/index.jsp</result>
</action>


</package>
  </struts>




当我么在浏览器上输入: http://locahost:8080/struts2/user!add?name=aa&pass=bb


那么,我么在Struts.xml的配置如下


<struts>
<package name="xx" namespace="/" extends="struts-default">
<action>/succ.jsp</action>
<!-- 
当我么在获取到URL的参数的时候进行帐号和密码的匹配如果不成功返回error并显示错误信息
-->
<action name="error">/error.jsp</action>
</package>
</struts>


Action:
public String name;
public String pass;


//上面需要提供Set()和Get()方法来获取URL上的参数


public String add(){
if(name == null || name.eques("xx")){
this.addFieldError("name","帐号错误...")
}


if(pass == null || name.eques("oo")){
this.addFieldError("name","密码错误...")
}
}






<s:param>再次了解此标签


如果我么这样使用<s:param name="username" value="'ZhangSan'"></s:param>
这样,name属性为一个字符串,而我么的value的值为一个Ognl表达式


<s:param name="username">ZhangSan</s:param>
而这种方式是在我么的页面中去指定的ZhangSan的字符串


如果我么使用上面的在标签中使用value那么就不可以在页面上指定字符串了




<s:url>与<s:param>的结合使用


<s:url id="url" action="test">
    <s:param name="id" value="123" />
    <s:param name="username" value="'ZhangSan'" />
</s:url>


<s:a href="%{url}">测试连接</s:a>


如果,我么这样写的话,直接运行,那么在页面显示的直接就是/struts2xuexi04/demo/test.action?id=123&username=ZhangSan
连我么的Action程序都不会被执行的,如果我么写下<s:a>那么会生成一个链接,查看源码发现链接被转换成
<a href="/struts2xuexi04/demo/test.action?id=123&amp;username=ZhangSan">测试连接</a>
并且点击链接的时候,我么会执行Action程序。


所以,<s:param>一般作为<s:url>的子标签使用,传递参数




再次了解<s:set>标签的使用


<s:set var="myKey" value="#paramenters.sore[0]" scope="page"></s:set>


其中,#paramenters是我么的context上下文对象,而.sore[0]就是属性


<s:set var=”myVar” value=”#parameters.score[0]” />
<s:property value="#myVar" />   ----->   ActionServlet.getContext().get("myVal")
<s:property value="#request.myValue" />   -----> ActionServlet.getContext().getRequest.get("myVal");






Action的一些常量介绍:

细说常量定义:常量的设定一般在Struts.xml或者在Struts.properties中进行配置的,两种配置方法如下:


<struts>
<constant name="struts.action.extension" value="do" />
</struts>


在Struts.properties中的配置
struts.action.extension = do


应为常量可以在多个配置文件中进行定义,所以我么需要了解Struts2加载常量的搜索顺序


Struts-default.xml
Struts-plugin.xml
Struts.xml
Struts.properties
web.xml


如果在多个文件中配置了同一个常量,则最后一个文件中配置的常量值会覆盖前面文件中配置的常量值






Struts2中一些常用的常量介绍:


<!-- 设置浏览器是否为缓存静态内容,默认值为true(使用环境下使用)开发阶段最好关闭 -->
<constant name="struts.serve.static.browserCache" value="false" />




了解自定义转换器:


在我么的Struts2中有自带的转换器没人会愿意自己手动进行转换的,但是还是大概了解一下把。


如何编写一个自定义转换器?
1.继承StrutsTypeConverter,并且实现两个方法


public class UserConverAction extends StrutsTypeConverter{

//将字符串转换成一个User对象
public Object  convertFromString(Map context, String[] values, Class toClass) {


//values就是获取到么表单上的参数
String value = values[0];
String splites = value.split(",\\s*");
return new User(splites[0],splites[1]);
}


public String convertToString(Map context, Object o) {


//将对象转换成字符串
return o.toString();

}






2.虽然上面实现了,但是代码还不能运行,因为Struts2找不到我么自定义的转换器
 我么需要注册,struts才可以找到。


    * 局部注册:在UserConverAction包下创建一个properties文件,创建名为 Action名 - conversion.properties
即(UserAction-conversion.properties)其内容为   属性名 = 转换其类名  即(user = cn.action.UserConverAction)
 


    * 全局注册: 在src下创建名为xwork-convsion.properties的文件,内容为  属性名 = 转换器类名 即(cn.itcast.domian.User = cn.action.UserConverAction)




     有那么一点小小的区别就是全局注册对所以的User类型的Action属性使用类型转换器,而局部的只是当前包下的
     并且,当前包下的属性名可以不带包名,而全局的需要加入包名








知道<result>标签的type类型


1.dispatcher  : <result>默认就是此类行,跳转到jsp页面
2.redirect    : 重定向到一个jsp页面(url会发生改变)
3.chain      : 跳转到一个Action
4.redirecrAction : 从定向到一个Action(URL会发生改变)




了解一下,当我么跳转到另外一个Action中,如果它的namespace不是"/"而是其他的,那么使用什么方式进行跳转过去呢?


<result type=chain>
<param name="actionName">xxxx</param> //Action的名称
<param name="namespace">/succ</param> //namespace的值
</result>






文件校验之....xml校验和validate()校验




简单聊聊validate()校验,该校验比较简单,重写父类的validate()方法既可
该方法会在execute()方法之前执行。






 
我么需要重写父类的validate()方法,在这个方法中,完成对参数的校验,validate()在封装完参数后进行校验
在执行execute()方法,如果validate()方法向addFieldError()添加了错误信息,那么不会在执行execute()方法
而是跳转到input结果码对应的页面
 
这个只是一种校验方式,也不是我么重点学习的校验方式,我么重点学习,如何使用.xml进行我么的校验
 
@Override
public void validate() {

if(username == null || username.trim().isEmpty()){
this.addFieldError("username", "用户名不能为空");
return ;
}

if(password == null || password.trim().isEmpty()){
this.addFieldError("password", "密码不能为空");
return ;
}


}




代码校验流程,由于是记事本不支持图 - -!没办法咯


页面表单
  |
  |
  |
  |
  v
params拦截器
  |
  |
  |
  |
  v
conversionError拦截器
  |
  |
  |
  |
  v
validation拦截器 --------->  validation拦截器会执行Action的validate()方法,当校验失败后validation()方法应该向FieldError中
--------->  存放错误信息,这个时候需要调用ActionSupport类的addFieldError()方法
  |
  |
  |
  |
  v
workflow拦截器 --------->  workflow拦截器会检测fieldError中是否存在错误信息,如果存在,那么就会跳转到input结果码对应的页面
  |
  |
  |
  |
  v
 Action请求处理方法




那么,大体上就是这样经过前面几个拦截器,如果没有发现错误就会执行Action程序,发现错误就会跳转到input相对应的页面






上面的校验是对所有的进行校验,但是,我么只想对一登录或者注册进行这样的校验,如何去做呢
这个时候我么需要用到私有校验了


在我么的JSP有这么一段话
<form action="<c:url value='/xxxx_login.action' />" method="post">
<input type="text" name="xxxx" />
.....
</form>


在我么的Struts.xml中
<struts>
<package name="xx" namespace="/" extends="struts-default">
<action name="xxx_*" class="xxx.xxx.XmlAction" method={1}>

</action>
</package>
</struts>

在我么的XmlAction中


//私有校验的方法
public void validateLogin(){

if(username == null || username.trim().isEmpty()){
this.addFieldError("username","用户名不能为空");
}
}


@InputConfig(resultName="loginInput")
pulbic String login(){


System.out.println(username);
return NONE;
}


这样,我么可以对login这个方法进行单独的校验了。


需要注意的是,校验方法  前面必须是validate   后面是  请求处理的方法
而我么的login也需要加上"@注解",如果没输入用户名或者用户名过短,那么
就会出现loginInput这个错误,这个时候我么只需要在<result name="loginInput">
中进行配置相对应的页面即可。










那么,刚才上面我么已经了解到了validate()校验,那么现在,我么就来学习.xml文件进行校验的方法把


其实.xml校验方法并不是很难的,那么,如何去做呢?


看实例,来解说:


JSP:
<form action="<c:url value='/Xxx.action' />" method="post"> 
<input type="text" name="username" />
....
</form>


Struts.xml


<struts name="xx" namespace="/" extends="struts-default">
<action name="xxx" class="xx.xx.xx.XMlAction">

</action>
</struts>


Action
private String username;
private String password;
.....
提供Set()和Get()方法


public String execute() throws Exception {}
  
好的,上面已经做好了,那么接下来就是写.xml文件,该文件创建在与Action同包下


.xml的文件名是   Action名-validation.xml


那么,怎么去写这个.xml的配置呢
    *
我么可以去xwork-core-x.x.x.jar包中寻找一个 xwork-validator-x.x.x.dtd
这个文件中有一个在线的DTD约束文件
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
即这段copy到你的.xml文件中就行了,如果电脑没网络,就需要配置了
配置的方法 "百度一下"






   *
在配置好DTD后,接下来就是
<validators>
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>


.....
.....
</validators>


这样就可以对其进行相对应的配置了,那么他么怎么知道找哪个东东去处理呢?
好吧,这个你在com.opensymphony-xwork2.validator.validators中可以找到相对应的class属性值
例如 <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
对应的就是这个Class属性






这个类里面帮我么进行了校验 - - 所以不需要我么写代码了,由于本人太菜了,源码太深搞不懂Apache那些大神写的源码


好了,那么这样算是校验好了吗,NO,NO,NO....我么忘记在Struts.xml中写入<result name="input">了


如果我么输入出错,会出现input这个错误的






那么,刚才上面是全局的校验,如想我么想配置私有校验呢?如何去写呢,还是看实例说话


JSP
<form action="<c:url value='userAction_login.action' />" method="post">
<input type="text" name="username" />
.....
</form>


Struts.xml


<struts>
<package name="userAction_*" namespace="/" extends="struts-default">
<action name="xxx" class="xx.xx.xxx.UserAction">
<result name="loginInput">/xx/xx.jsp</result>
</action>
<package>
</struts>






Action:


private String username;
private String password;
.....
设置Set()和Get()方法


@InputConfig(resultName="loginInput")
public String login(){return NONE;}


以上这些代码和前面的并没有什么区别,只是.xml的文件名有区别而已,早知道这样我就直接说是.xml文件不同了, - -写的详细还嫌啰嗦!


那么这个文件名怎么如写呢?
*  Action类型
*  Action名
*  validation


假设我的文件名XmlUserAction


那么  XmlUserAction-userAction_login-validation.xml
这样才我么的.xml文件名才算是正确的,如果你不这样写,那么你的.xml文件形同与摆设

并不会进行校验









Struts2笔记还未写完,如有兴趣,欢迎关注我的博客




























































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值