struts2学习笔记-验证器
来源:互联网 发布:淘宝用红包退款 编辑:程序博客网 时间:2024/06/04 00:25
struts2验证:
1.前言(验证器的三种验证方法和两种验证类型):
三种验证方法:
1.第一种:覆写继承了ActionSupport的validation方法,实现局部和全局验证;
2.第二种:基于xml的验证方法,基于xml的方法也提供局部和全局验证,并且基于xml中的验证方法,中包含两种:一种字段验证,一种非字段验证;
3.第三种:使用注解方式: @SkipValidation 这个注解表示不对该方法进行验证。
使用struts2的validate框架有两种验证类型:
a):在服务端进行验证。
b):在客户端进行验证。
注意:如果需要使用validate框架在客户端进行验证的话,一定要使用 struts2 的s标签并且 表单 的theme不能 为:simple
2.什么时候null什么时候空?
答:没有提交这个参数就是null就是当你越过表单直接访问action的时候;
3.关于验证器的一些注意事项:
1).验证未通过,将不会执行相应的action方法;
2).验证在方法之前执行;
3). ^1[345678]\\d{9}$ 这是验证手机号的正则表达式(说明:这里是两个斜杠,因为markdown要转义);
4). 一定要指定 input 视图 不然会报错:报错信息如下:
严重: Could not find action or result
No result defined for action com.chenhao.action.ValidationTest and result input
4.struts.xml文件的相关的代码
(xml中的局部验证以下action配置不适用):
<action name="login" class="com.chenhao.action.ValidationTest" method="loginValidation"> <result name="success">success.jsp</result> <result name="input">validation.jsp</result> <!-- 这里就要指定input逻辑视图名 --></action>
5.覆写方法validation的验证:
在继承了ActionSupport的类中覆写validation实现 全局 的验证:
action类中的代码:
(关于name和mobile的setter和gettr省略)
public String loginValidation(){ System.out.println("login....."); System.out.println("name="+name); return "success"; }//这里是覆写了ActionSupport里面的方法; @Override public void validate() { // TODO Auto-generated method stub if(name==null||"".equals(name.trim())){ //如果filedErrors.size()>0则自动跳转到input视图; this.addFieldError("name", "用户名不能为空"); } if(mobile==null||"".equals(mobile.trim())){ //如果filedErrors.size()>0则自动跳转到input视图; this.addFieldError("mobile", "手机号不能为空"); }else if(!Pattern.matches("^1[345678]\\d{9}$", mobile)){//这里的正则是验证手机号的; this.addFieldError("mobile", "手机号格式错误"); } }
jsp页面的代码:
<form action="login.action" method="post"> 用户名:<input type="text" name="name"/><br> 手机号:<input type="text" name="mobile"/><br> gender 性别<br> <input type="submit" value="登录"/> </form>
在继承了ActionSupport的类中覆写validation实现 局部 的验证:
注意:在创建自定义的validate方法时需要注意该方法的方法名! 该方法名由 validate+对应的表单提交的action中的 执行方法名称(首字母大写);
//要去掉覆写注释->@Overridepublic void validateLoginValidation() { // TODO Auto-generated method stub if(name==null||"".equals(name.trim())){ //如果filedErrors.size()>0则自动跳转到input视图; this.addFieldError("name", "用户名不能为空"); } if(mobile==null||"".equals(mobile.trim())){ //如果filedErrors.size()>0则自动跳转到input视图; this.addFieldError("mobile", "手机号不能为空"); }else if(!Pattern.matches("^1[345678]\\d{9}$", mobile)){//这里的正则是验证手机号的; this.addFieldError("mobile", "手机号格式错误"); } }
这样写了之后,就只会验证这个方法,其余的方法都不会验证(这个方法名的含义是validation加上要验证的方法的方法名,方法名的第一个字母要大写);
6.基于xml方式验证:
1.使用XML方式检验需创建一个XML配置文件,位置在对应的Action同级目录下,命名规则为:Action名-validatioin.xml。
2.校验文件可以有两种写法,一种是字段校验,一种是非字段校验。字段校验就是以字段为主,在对应字段配置下添加该字段的校验器,非字段校验就是先定义好校验器,在校验器下添加字段。
使用xml方式的全局验证:
1.全局就是针对整个action对象进行xml验证;
2.当我们使用全局验证时候需要在 action 对象的同目录下创建一个xml配置文件;
3.文件名是由 : actionName + -validation.xml
使用xml方式的局部验证:
注意:struts.xml中的配置(这是相应的表单提交的action名称也要变):
<struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <package name="default" namespace="/" extends="struts-default"> <action name="login_*" class="com.chenhao.action.ValidationTest" method="{1}"> <result name="success">success.jsp</result> <result name="input">validation.jsp</result> </action> </package></struts>
1.局部验证是针对action对象中的某一个方法进行xml验证;
2.使用局部验证的时候同样要在 action对象的同目录下创建一个xml配置文件;
3.不过使用局部验证需要在struts.xml 中进行配置;
4.文件名由: actionName- + methodName(如:login_local) + -validation.xml
短路校验:
在字段校验或者非字段校验中加入:short-circuit=”true”,如果某个被标记为短路的校验器失败了,将会阻止其他后续的校验器的进行,然后一个错误(action错误或者字段错误,取决于校验器的类型)将会被添加到被校验的对象的ValidationContext中.
<validator type="expression" short-circuit="true"> <!-- 短路 校验器 --> <param name="expression">email.startsWith('mark')</param> <message>Email does not start with mark</message> </validator>
短路校验器的规则:
1.当非字段校验器校验失败,则其后的所有字段校验器都不会执行,而不会影响其他非字段校验器;
2.字段校验器校验失败时,其后的所有字段校验器都不会执行;
注:当执行到短路,报错时,后面的字段校验器不再执行,不影响非字段校验器;
指定action中要校验的属性,指定校验器,上面指定的校验器requiredstring是由系统提供的,系统提供了能满足大部分验证需求的校验器,这些校验器的定义可以在xwork-2.x.jar中的com.opensymphony.xwork2.validator.validators下的default.xml`中找到。
为校验失败后的提示信息,如果需要国际化,可以为message指定key属性,key的值为资源文件中的key。
非字段型校验器是以校验器为单位的,内容模板:
<validator type=""> <!-- 校验规则器名 --> <param name="fieldName"></param> <!-- 要校验的属性名 --> <param name=""></param> <!-- 要校验的属性名 --> <message></message> </validator>
字段型校验器是以属性为单位的,内容模板:
<field name=""> <!-- 要校验的属性名 --> <field-validator type=""> <!-- 校验规则器名 --> <param name=""></param> <!-- 校验器要使用的参数名 --> <message></message> </field-validator> </field>
校验器的运行顺序
1.非字段校验器比字段校验器先执行;
2.从前往后执行;
action类的执行原理及顺序:
1).类型转换;
类型转换失败是在Action调用相应属性的set方法之前发生的,类型转换失败,不影响程序的运行;
2).set方法;
无论类型转换是否成功,都将执行该属性的setter方法.只不过,类型转换失败,会设置该属性值为null;
3).数据验证;
当验证器对通过set方法设置的属性值进行验证时,若验证失败,则会将验证失败信息写入到一个专门的集合中fieldErrors集合.当所用数据验证完毕后,若fieldErrors集合中存在异常信息,即集合的size()大于0,则workFlow拦截器会返回一个”input”字符串,使请求转发到input视图.请求将无法到达Action,即无法执行Action方法;
当然,若在类型转换时已经发生异常,不仅会将异常信息写入到fieldErrors集合,还会继续执行该属性的set方法,将null值赋予该属性.该属性接受到的为null值,肯定不是用户输入的期望的值,所以在进行数据验证时,也一定会验证失败.此时的验证失败信息也同时会写入到fieldErrors集合;
4).Action方法;
经过上面的执行,如果系统中的fieldErrors集合存在异常信息,系统会自动将请求转发至input视图.如果系统中的fieldErrors没有任何异常信息,系统将执行Action方法;
在Action中获取ServletAPI:
为避免与Servlet API耦合,Struts2对HttpServletRequest,HttpSession,ServletContext进行了封装,构造了三个Map对象来替代这三种对象.当然,也可以获取到真正的这三个Servlet的API.
1.通过ActionContext获取(重要);
在struts2框架中,通过Action的执行上下文类ActionContext,可以获取request/session/application对象;
ActionContext ctx = ActionContext.getContext();
Map
额外学习:在eclipse中rename时:alt+shift+r 和 f2 两个组合快捷键都可以换名称;
//方法一://下面的方式获取到的仅仅是对这些ServletAPI的域空间,//而不是真正的ServletAPI//向request域空间中放入数据(注意:暂且这样认为放入到的request域空间中数据,当学了后面的值栈//后就知道,这种理解是不对的)ActionContext.getContext().put("req","req_value");ActionContext.getContext().getSession().put("ses", "ses_value");ActionContext.getContext().getApplication().put("app", "app_value");
2.通过ServletActionContext获取(重要);
//以下获取的是真正的ServletAPI//方法二:HttpServletRequest request= ServletActionContext.getRequest();request.setAttribute("req", "req_name_value");//向session域空间中放入数据;request.getSession().setAttribute("ses", "ses_value");//向application(ServletContext)域空间中放入数据; ServletActionContext.getServletContext().setAttribute("app","app_name");
3.通过实现特定接口来获取(了解就好);
注:学会区分成员变量!!
package com.chenhao.action;import java.util.Map;import org.apache.struts2.interceptor.ApplicationAware;import org.apache.struts2.interceptor.RequestAware;import org.apache.struts2.interceptor.SessionAware;public class ValidationTest implements RequestAware,SessionAware,ApplicationAware { //这里设置成员变量,接受覆写方法传过来的参数; private Map<String,Object> req; //成员变量 private Map<String,Object> ses; //成员变量 private Map<String,Object> app; //成员变量 public String local(){ req.put("req", "req_value"); ses.put("ses", "ses_value"); app.put("app", "app_value"); return "success"; } @Override public void setApplication(Map<String, Object> arg0) { // TODO Auto-generated method stub this.app = arg0; } @Override public void setSession(Map<String, Object> arg0) { // TODO Auto-generated method stub this.ses = arg0; } @Override public void setRequest(Map<String, Object> arg0) { // TODO Auto-generated method stub this.req = arg0; }}
struts2的基石–拦截器:
struts2内置了很多拦截器,每个拦截器完成相对独立的功能,多个拦截器的组合体称为拦截器栈.最为重要的拦截器栈是系统默认的拦截器栈DefaultStack;
前言:1)当拦截器验证错误,默认转向Action.INPUT 即”input”’
2)或者用注释:@InputConfig(methodName=” 方法名”,resultName=”视图”),如果methodName方法为空或者指定方法不存在时,转向resultName指定视图,使用了该标注,将不再转向”input”视图;
1.拦截器的自定义与注册;
需要步骤:
1.建立一个继承了AbstractInterceptor的拦截器类;
2.自定义的拦截器要在struts2的配置文件中注册;
例子 :权限拦截器:
创建一个拦截器类:
import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class PermissionIntercept extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("-----------------------------"); //获得session中的用户信息; String user = (String)ActionContext.getContext().getSession().get("user"); if(user != null){ //调用action return invocation.invoke(); } return "error"; }}
在Struts2中的配置:
<package name="default" namespace="/" extends="struts-default"> <!-- 这里注册已经创建的拦截器 --> <interceptors> <interceptor name="permissionIntercept" class="com.chenhao.action.PermissionIntercept"> </interceptor> </interceptors> <action name="login_*" class="com.chenhao.action.SysAction" method="{1}"> <!-- 这里调用已经创建好的permissionIntercept拦截器; --> <interceptor-ref name="permissionIntercept"/> <!-- 因为调用了自定义的拦截器,所以不会在调用默认拦截器,所以这里人为调用,完成一些基本的操 作 --> <interceptor-ref name="defaultStack"></interceptor-ref> <result name="error">error.jsp</result> <result name="success">loginout.jsp</result> </action></package>
login.jsp页面
<body><form action="login_execute.action" method="post"> <input type="submit" value="submit"/> <!-- 这里设置一个session --> <% session.setAttribute("user", "任辰皓") %> </form></body>
loginout.jsp页面
<body> <!-- 这里移除session --><% session.removeAttribute("user");%> 成功退出!!!</body>
Action无特殊设置,直接定义一个Action,方法名与所调用的一致就行 ,….省略….;
2.拦截器的另一种定义的方式(拦截器栈);
把上面在Struts2中的配置如下修改就可以了(其余jsp,action等都不变);
<package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="permissionIntercept" class="com.chenhao.action.PermissionIntercept"> </interceptor> <interceptor-stack name="permissionStack"> <interceptor-ref name="permissionIntercept"/> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="login_*" class="com.chenhao.action.SysAction" method="{1}"> <interceptor-ref name="permissionStack"></interceptor-ref> <result name="error">error.jsp</result> <result name="success">loginout.jsp</result> </action></package>
3.设置默认的拦截器:
说明:为了减少冗余的代码量;
只需要在struts2中配置:
<package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="permissionIntercept" class="com.chenhao.action.PermissionIntercept"> </interceptor> <interceptor-stack name="permissionStack"> <interceptor-ref name="permissionIntercept"/> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 只需要在这里建一个默认拦截器,这个包里面的所有action执行时都会执行它,如果在action中单独指明了一个拦截器,那么就不会执行默认的拦截器 --> <default-interceptor-ref name="permissionStack"> </default-interceptor-ref> <action name="login_*" class="com.chenhao.action.SysAction" method="{1}"> <result name="error">error.jsp</result> <result name="success">loginout.jsp</result> </action></package>
OGNL的使用:
1.特点(相对于其他表达式语言,它提供了更加丰富的功能):
1.支持对象方法的调用;
2.支持类静态方法的调用和常量的访问:格式为:
@全类限定名@方法名 |常量名;
对于静态方法的访问,需要通过在struts2的配置文件struts2.xml中设置常struts.ognl.allowStaticMethodAccess=true;
3.可以操作集合对象;
4.可以直接创建对象;
2.值栈与OGNL(值栈就是根对象):
对于struts2中的值栈的学习,主要是要搞清楚以下几个对象间的关系:
1.值栈与ActionContext的关系;
2.值栈与值栈的Context属性的关系;
3.值栈的Context属性与ActionContext的关系;
它们的关系,通过以下几个知识点可以加深理解.
1)值栈对象:
A.值栈的实现类:
在用户提交一个Action请求后,系统会马上创建两个对象:Action实例与值栈对象.
struts2中的值栈ValueStack是个接口,其实现类为OgnlValueStack.
//额外学习:// java中属性 和 成员变量的区别:有get or set方法为 属性;
B.root的属性的类型:
本质是一个ArrayList,不过在这里当做栈使用;
C.Context属性的创建:
在设置root的时候创建;Context本质是一个Map;
2).值栈的获取很麻烦:
当一个Action请求到来是,不仅会创建一个Action实例,还会创建一个ValueStack对象,用与存放当前Action运行过程中的相关数据.当请求结束,Action实例消失,用于记录其运行期间数据的值栈也没有了意义.所以,当请求结束时,同时需要将值栈对象销毁.即值栈的生命周期与请求Request的相同.为了保证这一点,就将值栈对象通过setAttribute()方法,将其放入到了Request域属性中,并将该属性的key以常量的形式保存在ServletActionContext中.所以,为了获取值栈对象,首先需要获取到request对象,然后再获取其key,这样才能获取到值栈对象.这个过程相对是比较麻烦的.
值栈的实质是request中的一个属性值.这个属性的名称为:struts.valueStack,保存在ServletActionContext的常量是STRUTS_VALUESTACK_KEY中.
public String execute(){ //从request中获取ValueStack对象 String key = ServletActionContext.STRUTS_VALUESSTACK_KEY; HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStack) request.getAttribute(key); return "success";}
3).context属性的别名:
1).ActionContext是context属性的别名;
怎么证明了,看下面这行(ActionContext.getContext().put(“city”,”shanghai”))代码,把语句//1 或者放在//2看看jsp页面输出的信息,可以看出来,context和ActionContext是一样的;只不过ActionContext是context的别名;
@Override public String execute() throws Exception { ActionContext.getContext().put("city","shanghai"); //1 //放在这里jsp页面输出beijing String key = ServletActionContext.STRUTS_VALUESTACK_KEY; HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStack) request.getAttribute(key); //从ValueStack中获取其属性context; Map<String,Object> context = vs.getContext(); context.put("city", "beijing"); //2 //放在这里输出shanghai; return "success"; }
<!-- 这是jsp页面的代码 -->city = <s:property value="#city" /> <!-- 要在表达式中访问到context中的对象,需要使用“#对象名称”的语法规则-->
以上同一个语句在不同位置输出不同的内容就能说明context和ActionContext是一样的,理由见上面的代码,后者把前者覆盖了;
注意:为了方便获取值栈的context属性,Struts2专门为其又起了个别名—-ActionContext,无论是ActionContext中存放的非根对象,还是值栈中context中存放的非根对象,它们均使用了同一个Map.即它们是同一个对象;
4).值栈的获取很简单:
为了方便对值栈的访问,于是就将值栈对象直接放到了context这个Map中.通过查看OgnlValueStack的对root的初始化方法setRoot()可以看到.
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor,CompoundRoot compoundRoot,boolean allowStaticMethodAccess) { this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); //OGNL其实和struts2没有联系; this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); //就是这句代码!! context.put(VALUE_STACK, this); Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false);}
//所以,ActionContext这个Map中,最终存放者如下内容(你会发现context又是ActionContext):// | |->root// |->valueStack-->|// |->request |->context(即ActionContext)//ActionContext |->session// |->application// |->...// |////向context中放入数据,就是向map中放入数据,需要指定key.struts2中已经定义号一些key,用于完成特殊功能.访问context中数据,即为非根数据,需要使用 # ;// |-->application// |-->session// |-->value//context map-- |-->action// |-->request// |-->parameters// |-->attr(searches,page.ruquest,session,then,application,scopes)//说明:ValueStack的context中存放的是ActionContext的地址(只是一个引用)//额外获得知识:域属性中存放的是引用(地址),不是对象;
//从request中获取Value对象;ValueStack vs2 = ActionContext.getContext().getValueStack();
5).值栈的栈操作:
查看OgnlValueStack类中的peek(),pop(),push()方法可知,对ValueStack对象的栈的操作,本质是对root栈对象的操作.即,从宏观上可以直接说值栈就是根对象.但,其实根对象指的是值栈的root对象,而非根对象是值栈的context对象.
6).值栈操作:
这里的值栈指的是宏观上的值栈,即包含根对象root与非根对象context.对于值栈的操作包括两方面:向值栈中放入数据,从值栈中读取数据.值栈中的数据,可以通过struts2标签显示:
向值栈中放入数据分为两种,一种为显示放入,一种为隐式放入.所谓显示放入是指,显示的获取到值栈对象,然后向其中放入数据隐式放入是指,没有专门将数据直接放入值栈对象中的代码,却已经将数据放入.
Struts2中有一个标签 便于对值栈中数据的存放情况进行了解.其在页面上显示为一个可展开/关闭的连接;
1)搭建测试环境:
step1.定义实体Student(将来是要放到数据库的);
相当于定义一个JavaBean;
Step2.定义Action;
就是获得值栈;
Step3.注册Action;
Step4.定义视图页面show;
2).向root中显示放入数据;
@Override public String execute() throws Exception { String key = ServletActionContext.STRUTS_VALUESTACK_KEY; HttpServletRequest request = ServletActionContext.getRequest(); ValueStack vs = (ValueStack) request.getAttribute(key); //在root中显示的放入了一个无名对象的方式一; Student student = new Student("张三",23); vs.getRoot().push(student); //在root中显示的放入了一个无名对象的方式二; Student student2 = new Student("李四",25); vs.push(student2); //--------------------------------------------------------------------------------- //放入有名对象的思路:先把对象放入Map,在再把Map放入一个ArrayList中就是一个有名的对象了; //放入一个有名的对象的方法一; Student student3 = new Student("liu四",25); Map<String,Student> map = new HashMap<String,Student>(); map.put("student3", student3); vs.push(map); //放入一个有名对象的方法二; Student student4 = new Student("liu456四",65); //查看set()的api可知,set()的调用,set()方法中的实现是,先查看栈顶元素有否有Map,有就使用, //没有就new一个 vs.set("student4", student4);//用set()方法就不需要像放入 "有名对象的方法一"麻烦了; //将root当做是ArrayList放入数据 //这个和前面的不同这个通过add()会被放入栈底; Student student5 = new Student("liu456四",65); vs.getRoot().add(student5); return "success"; }
jsp访问方式:
<s:debug/><br> <!-- 一种调试标签,详细的百度 -->name = <s:property value="name"/><br>age = <s:property value="age"/><br>name = <s:property value="student3.name"/><br>age = <s:property value="student3.age"/><br>name = <s:property value="student4.name"/><br>age = <s:property value="student4.age"/><br>
3).向root中隐式放入数据;
//root中隐式放入数据 重点掌握//在action中定义要提交的属性名,并指定set,get方法,这就是向值栈中隐式的放入数据;
4).向context中显示放入数据;
//向ActionContext中显示添加数据,就是以下的形式;ActionContext.getContext().put("some","req_value");//这句话相当于;--------------------->---- |// |-->application |// |-->session |// |-->value |//context map-- |-->action(the current action)这是一个引用 |// |-->request |// |-->parameters |// |-->attr(searches,page.ruquest,session,then,application,scopes) |// |---->some //就会被添加到这里---<-------------------------------<---------|
5).向context中隐式放入数据;
注意:以下两类的参数是隐式的放入的
A.请求参数
B.Action对象
//额外知识:在网页中由表单提交的数据在服务端接受的时候都是由 数组 接受的,因为它要兼顾一个参数多个值的情况//比如:复选框就是一个参数多个值的情况;
<!-- jsp中的页面代码 --><%-- 当Action中没有name和age的属性声明时,以下就只有parameters.name--> <!-- #parameters.name底层执行的是request.getParameters("name") 读的是参数,所以在action类中尽管没有相应属性的set,get方法一样可以读到 --><s:property value="#parameters.name"/><br><!-- #request.name底层执行的是request.getAttribute("name") 读的是属性值 --> <s:property value="#request.name"/><br><s:property value="#action.name"/><br>
当请求到来,马上创建一个action对向,在root和context中都要放入一个action对象;
6).数据的加载顺序;
A.root中数据的加载顺序:
当在Action中仅仅向context放入某数据some后,页面无论是通过#从context中读取数据,还是不使用#直接从root中读取数据,均可得到放入的值,就是先在root中查找没有再在context中查找;
public class ValidationTest extends ActionSupport { public String local(){ ActionContext.getContext().put("some","req_value"); return "success"; }}
jsp页面:
some=<s:property value="some"/><br> <!-- 在root目录中也能读取是因为,struts2的内部实现的支持,如果在root中找不到,struts2的内部实现会到context中去寻找; -->some=<s:property value="#some"/><br><!-- -->
B.request中数据的加载顺序:
request.some底层执行的是request.getAttribute("some"); #request.some被struts2包装后的查找顺序是: 1).request域空间; 2).root 3).Context
//用ServletActionContext 可以把参数放入request中去;//ActionContext.getContext().put("some","req_value");这行代码不能真正的把属性传入request中,只是传入了context中,正确方法如下:HttpServletRequest request = ServletActionContext.getRequest();request.setAttribute("some","req_value");
7).OGNL对于集合的操作(此节内容了解即可):
Struts2 中使用OGNL对于集合的操作主要涉及以下集中情况:
1),创建List与Map集合;
2),遍历List与Map集合;
3),集合元素的判断;
4),集合投影;
5),集合过滤;
A.创建List与Map集合:
注:以下的代码只有jsp页面中有,无其他代码;
<br>------------------list--------------------- <!-- 在s:set中定义的都直接当如到了context中 --> <s:set name="mylist" value="{'zs','ls','ww'}"> </s:set><!-- iterator标签默认会将当前迭代对象放入到值栈栈顶 --> <s:iterator value="#mylist"><br> <s:property/><br><!-- property标签默认会输出值栈栈顶元素 --> </s:iterator>
<br>------------------map--------------------- <!-- Map定义是 # 开头 --> <s:set name="myMap" value="#{'moblie':'1234567','QQ':'923047' }"/> <!-- 方法一 --> <s:iterator value="#myMap" var="entry"> <s:property/><br> </s:iterator> <!-- 方法二 --> <s:iterator value="#myMap" var="entry"> <s:property value="entry"/><br> </s:iterator> <!-- 方法三 --> <s:iterator value="#myMap"> <s:property value="key"/> = <s:property value="value"/><br> </s:iterator>
B.集合元素的判断:
判断 ‘zs’ 是否在集合里面?
<!-- 需要 A 的代码.in 表示是否在? not in表示是否不在? --><s:property value="'zs' in #myList"/><br><s:property value="'zs' not in #myList"/>
C.集合投影:
注:集合查询:指对于集合中的所有的数据(相当于行),值选择集合的某个属性值(字段)作为一个新的集合.即:行数不变,只选择列;使用如 “集合.{字段名} “的语法投影;
注:需要建个实体类(例子中,新建的一个叫Student的实体类,并且其中有 ame 和 age 属性 )!
<br>-------------------创建三个Student实体类对象------------------ <s:bean id="Student1" name="com.chenhao.action.Student"> <s:param name="name" value="'zhangsan'"></s:param> <s:param name="age" value="34"></s:param> </s:bean> <s:bean id="Student2" name="com.chenhao.action.Student"> <s:param name="name" value="'zsan'"></s:param> <s:param name="age" value="34"></s:param> </s:bean> <s:bean id="Student3" name="com.chenhao.action.Student"> <s:param name="name" value="'zhangn'"></s:param> <s:param name="age" value="34"></s:param> </s:bean> <br>-----------------将前面的三个student对象的name属性组成一个List,方便映射-------------------- <s:set name="students" value="{#Student2,#Student3,#Student1}"></s:set> <s:iterator value="#students"><br> <s:property/> </s:iterator> <br> <br>----------------集合的映射-------------------- <!-- 只要几个元素的某一个属性,例如下面只要students的name属性,这就叫集合的投影 --> <s:set name="studentNames" value="#students.{name}"></s:set> <s:property value="studentNames"/><!-- 说明:在<s:bean/>中的name属性里的值为实体类的权限定名 -->
D.集合的查询:
注:以下的代码需要 上面 B 中的代码!!!!
<br>---------------集合的查询---查询前面的三个Student对象中年龄大于23岁的 所有人---------------- <s:iterator value="#students.{? #this.age > 23}"><br><!-- ? 代表所有人 --> <s:property/> </s:iterator> <br>---------------集合的查询---查询前面的三个Student对象中年龄大于23岁的 第一个人-------------- <s:iterator value="#students.{$#this.age > 23}"> <br> <!-- $ 代表第一个人 --> <s:property/> </s:iterator>
- struts2学习笔记-验证器
- struts2学习笔记4-验证
- Struts2学习笔记05----Struts2验证机制
- Struts2学习笔记(十九) 验证码
- struts2验证框架学习笔记_转载
- Struts2学习笔记二(数据验证)
- struts2第十四讲学习笔记,手动验证与框架验证
- struts2 验证 笔记
- J2EE系列之Struts2学习笔记(十九)--Struts2验证框架(内置验证)
- J2EE系列之Struts2学习笔记(二十)--Struts2验证框架(自定义验证)
- Struts2学习笔记(五)——服务端验证以及拦截器过滤器
- Struts2学习笔记2 ――表单验证
- struts2系列学习笔记(9)---------------编程方式的验证
- struts2系列学习笔记(10)---------------配置方式的验证1
- Struts2学习笔记——方法验证技术
- Struts2学习笔记——框架验证技术
- Struts2 学习笔记 08 简单的数据验证
- struts2的表单验证 ,消息处理学习笔记
- 第2章 在 HTML 中使用 JavaScript 优先使用外部引用脚本方式
- 解决QT5.8 for android 无法连接64位Mysql的问题
- 【MQ】Centos7搭建双主双从RocketMQ集群
- 557. Reverse Words in a String III
- XML解析之使用DOM4j操作XML文档
- struts2学习笔记-验证器
- Jin Ge Jin Qu hao UVA
- Codechef A temple of Snakes(思维)
- Linux文件锁flock
- 05-树7 堆中的路径 (25分)
- SurfaceFlinger整合layer的过程
- 自定义控件一带清除和抖动功能的EditText
- redis中bitmaps使用介绍
- java学习笔记00_泛型的(完成)