struts2标签是OGNL标签
OGNL标签基本分类结构——表单标签,非表单标签,流程控制标签,数据访问标签,
表单标签:主要用于生成HTML页面,和form表单元素,以及普通表单元素的标签
非表单标签:用于生成页面的tree或者table,用的不多
流程控制标签:用于实现循环等流程的
数据访问标签:主要包含用于输出,
表单标签:
新建web工程,搭建struts2框架,建包com.jikexueyuan.bean写实体类
package com.jikexueyuan.bean;
public class Users{
private id;//写一个编号
private String username;
private String password;
public String getUsername() {
returnusername;
}
publicvoid setUsername(String username) {
this.username= username;
}
publicString getPassword() {
returnpassword;
}
publicvoid setPassword(String password) {
this.password= password;
}
publicint getId() {
returnid;
}
publicvoid setId(int id) {
this.id= id;
}
}
建包com.jikexueyuan.action中建LoginAction.java
public class LoginAction extendsActionSupport
{
privateUsers us;
publicString execute()throws Exception{
System.out.println(us.getUsername);
return“success”;
}
publicUsers getUs()
{
returnus;
}
publicvoid setUs(Users us)
{
this.us=us;
}
}
然后写struts.xml文件
然后打开index.jsp
要使用struts2的标签就要加这句,引入struts2的支持
<%@taglib prefix=”s” uri=”/struts-tags”%>其中s表示本页面中,使用struts2标签的一个简写,一般都用s来代替
<body>
<!--编写表单-->这个表单同html表单很像,也有action,但是此处的action不需要加任何空间什么的,直接写struts.xml中的action 的name就可以了,也不需要加<%=path%>,也不需要加.action 或者.do了
当然method还是要写的
<s:formaction="slogin" method="post">
<s:textfield lable="用户名" name="us.username"/>编写两个输入标签,为什么此处写us, 是因为相对应于LoginAction,即提交数据的action,里面封装的对象us
<s:password lable="密码" name="us.password"/> lable属性是表单显示的名字,代码中不需要加:,显示页面的时候会自己加:并且两项做了自动换行,提交也做了自动换行,即struts会自动提供一些样式
<s:submit value="提交" /> 名字没有什么变化,
多选
(1)<s:checkboxlistname=“hobby1” lable="爱好"list="{'打篮球','下棋','唱歌'}"/> list中需要给它一个集合,注意{}里为单引号,给它一个name值,name是自己命名的,这样list列表会自动显示到里面来
这种情况下,点击页面显示源码,可以看到,value=“唱歌”显示也是唱歌
(2)实际使用时,list中应该存的是id号而不是实际的值
首先要加一个#,因为这儿不是一个普通的List集合,而是Map集合
<s:checkboxlist name=“hobby2”lable="爱好"list="#{'1':'打篮球','2':'下棋','3':'唱歌'}"/>
这种情况下,点击页面显示源码,可以看到,value=“3”,显示是唱歌
单选
<s:radio name=“hobby3”lable="爱好"list="{'打篮球','下棋','唱歌'}"/>
同理也可用第二种
<s:radio name=“hobby4”lable="爱好"list="#{'1':'打篮球','2':'下棋','3':'唱歌'}"/>
下拉列表
<s:select name=“hobby5”lable="项目" list="#{'1':'篮球','2':'棋','3':'唱歌'}"/>
下拉列表有个属性,multiple="true"这个属性的效果是,不再下拉,都能看到,直接去选择
多行文本块
<s:textarea name="xx"lable="简述"rows="22" cols="50"/>
级联菜单
<s:doubleselect
list="{'我爱西红柿','我爱番茄'}"
doubleList="top=='我爱西红柿'?{'斗破苍穹','xx修仙传'}:{'斗破宇宙','斗牛'}"<!--此处,top=='我爱西红柿'就是简单判定,即第一个如果显示的是“我爱西红柿,那么后面跟着的,所要级联的数据”,:后面跟着的是另一个人的信息-->
doubleName="作者" name=""/>
<s:optiontransferselectdoubleList=""list="" doubleName=""/>
具体:
<s:optiontransferselect
label="喜欢的书"
name="cnbook"
leftTitle="中文书籍"
list="#{'1':"java编程思想','2':"'企业实战'}" 以最实用的Map集合给放进去
listKey="key"
listValue="value"
multiple="true"
rightTitle="英文书籍"
headerKey="cnkey"
emtyOption="true";表示有空白选项
headerValue="请选择中文书籍"
doubleList="#{'1':"java','2':"'J2EE'}"
doubleListKey="key"
doubleListValue="value"
doubleHeaderKey="enKey"
doubleHeaderValue="请选择英文书籍"
doubleEmtyOption="true"
doubleMultiple="true"
doubleName="enbooks"/>
<s:/>
</s:form>
</body>
实例:——实现动态级联下来
package com.jikexueyuan.bean;
public class Em{//创建员工的实体类
private int eplId;
privateString username;
自动生成get和set方法
再自动完成构造方法——选择shift+alt+s,选择GenerateConstructor using field,生成完后,将super()去掉
}
再创建一个实体类——部门
package com.jikexueyuan.bean;
public class Dep{
privateint dptId;
privateString dptName;
自动生成get和set方法
再自动完成构造方法——选择shift+alt+s,选择GenerateConstructor using field,生成完后,将super()去掉
}
新建Test.jsp
<body>
模拟,从action传递过来了request对象
<%
首先要创建集合对象,用来存储所有员工信息
Map<Dep,List<Em>> map =newHashMap<Dep,List<Em>>(); key值是Dep一个部门的实体类,对应一个list集合,list里实际上就是员工Em实体类,
模拟从数据库创建了一些数据,首先创建部门信息
Depde1=new Dep(1,"采购部");
Depde2=new Dep(2,"市场部");
Depde3=new Dep(3,"营销部");
创建集合,三个部门就有三个集合来存储各个部门相应的员工信息
List<Em>li1=new ArrayList<Em>();
List<Em>li2=new ArrayList<Em>();
List<Em>li3=new ArrayList<Em>();
再创建员工信息
Emem1=new Em(1,"小明");
Emem2=new Em(2,"小红");
Emem3=new Em(3,"小量");
Em em4=new Em(4,"小最");
Emem5=new Em(5,"小8");
Emem6=new Em(6,"小3");
Emem7=new Em(7,"小7");
将三个员工加入第一部门,再加入第二部门,第三个部门,这样三个部门就有员工信息了
li1.add(em1);
li1.add(em2);
li1.add(em3);
li2.add(em4);
li2.add(em5);
li3.add(em6);
li3.add(em7);
接下来把Map集合填充起来
map.put(de1,li1);即部门1的员工在部门1,部门1的对象对应于list1集合
map.put(de2,li2);
map.put(de3,li3);
最终把map集合放到request对象当中
request.setAttribute("map",map);
%>
<s:doubleselect
formName="form1"
lable="业务员"
list="#request.map.KeySet()" 注意#的意思是,从范围中找,此处是从request范围当中找map,因为放入request对象当中的是map所以此处写map。
.KeySet()就会把key值展示出来
name="depId"部门编号
id="comboId"
listKey="dptId"
listValue="dptName"因为list是map集合,所以按key和value
doubleName="eplId"
doubleId="comboDoubleId"
doubleList="#request.map[top]"
doubleListKey="eplId"
doubleListValue="username"
/>
</body>
但是注意:index.jsp中的form action不要写成login,类似于关键字,即,以后不要使用login来命名action,会出错
流程:jsp表单写入数据时,提交到sloginaction,sloginaction又跳转会index.jsp,出现了 用户名自动回填,即只用使用struts2标签,就存在值的自动回填.
逻辑控制标签
<%@taglib prefix=”s”uri=”/struts-tags”%>
<body>
【1】 <!--学习<s:set>标签:作用向各种域存放一个值,值的类型可以是普通变量,scope是取值范围-->
以下是基本数据类型的存放
【1.1】<s:set name="age1"value="60"/>即默认写s:set的话,会向request和pageContext中放入名称为age的值,session和application都得不到的。
这句话的意义相当于java中的<%request.setAttribute("age",60)%>
<%=request.getAttribute("age")%><!--用来验证s:set是不是放到了request是上下文存储对象当中了-->结果直接显示在了jsp页面
<%=pageContext.getAttribute("age")%><!--pageContext是页面集对象-->
【1.2】若加入scope
<s:set name="age2"value="60" scope="session"/>加入scope="session"后,这时session范围就能获得age的值了
<%=session.getAttribute("age")%>
<s:set name="age3" value="60"scope="application"/>加入scope="application"后,这时application范围就能获得age的值了
<%=application.getAttribute("age")%>
存放的是集合
【1.3】<s:set name="bookList" value="{‘斗破苍穹’,'凡人修仙传',‘吞噬天空’}"/>此处的value就不是一个值了,而是一个集合,集合要用{}来表示
展示上面的集合数据:
展示的第一种方式:
<s:select label="书籍" list=“#bookList”/>此处的list中写的内容是上面的放入request对象中的bookList
【1.4】存放Map集合
<s:setname=”bookMap” value=”#{‘1’:’ 斗破苍穹’,’2’:’ 凡人修仙传’,’3’:’ 吞噬天空’}”/>
注意,在放入此处要放一个#,用于区分Map和List,#{}表示{}中放的数据是Map集合形式
展示数据:
<s:select label=”书籍map” list=”#bookMap”listKey=”key” listValue=”value”>
注意:使用Map集合的时候,展示数据时,要写listKey=”key” listValue=”value”,也就是说,map中的key值相当于这个里面的key值
上述两种的区别:
展示页面——右键查看源文件——
List的value就是斗破苍穹
Map的value是1。此中类型比较适合于平时的应用,在我们应用到这种下拉列表时,只需从action中传递过来map集合,直接把map集合,放到
<s:select label=”书籍map” list=”#bookMap”listKey=”key” listValue=”value”>就可以出现一个下拉列表了。不需要手动编写了。
【1.5】如何显示出这些值
<s:property value=”#age1”/> 此为默认的方式,注意#
<s:property value=”#session.age2”/>由上面可知,age2在session范围内,默认的方式是从request获取,所以,要加session. ,将范围明确告诉他
显示list集合数据
<s:property value=”#bookList”/> 可以把集合的数据全部输出出来
显示list集合中的某一个元素,需要加[ ]
<s:property value=”#bookList[1]”/> 展示的为下标为1的元素,list下标从0开始
如果list里为复杂数据类型,如对象,对象中才是一个具体的值
<s:property value=”#bookList.{放具体属性}[0]”/>
显示map集合
直接打印map集合<s:property value=”#bookMap”/>
打印出所有的key值<s:property value=”#bookMap.keys”/>——即输出[1,2,3]
打印出所有的value值<s:property value=”#bookMap.values”/>——即输入[斗破苍穹,凡人修仙传,吞噬天空]
【1.6】if语句——<s:if <s:elseif <s:else>
<s:set name=”score” value=”80”>
<s:if test=”#score>=60”> test里写逻辑表达式
及格
</s:if>
<s:elseif test =”#score>30”>
学渣
</s:elseif>
<s:else>
学沫
</s:else>
【1.7】迭代器——用来遍历数据<s:iterator>
(1)遍历list
<s:iterator value=”#bookList” id=”bookName”>起名字叫bookName,意义是bookList中的每一项,相当于i
<s:property value=”bookName”/> 会不停循环,把集合中的元素拿完为止
</s:iterator>
输出样式——斗破苍穹 凡人修仙传 吞噬天空
【与之前的输出结果相比,没有了[]和,】
(2)遍历Map——注意map的时候就不需要id了,因为map中有key值,通过key值遍历
<s:iteratorvalue=”#bookMap”>
<s:property value=”key”>
<s:property value=”value”><br> br为换行
</siterator>
输出的样式为:1 斗破苍穹
2 凡人修仙传
3 吞噬天空
【1.8】模拟从action中传递过来一个集合,集合中是对象
<%
List<Em> list = new ArrayList<Em>(); 创建一个list集合
Em em1=new Em(1,"小明"); 创建员工信息
Em em2=new Em(2,"小红");
Em em3=new Em(3,"小量");
Emem4=new Em(4,"小最");
有了4个对象,把数据放到list集合中
list.add(em1);
list.add(em2);
list.add(em3);
list.add(em4);
最后把list集合整体放到request对象中去
request.setAttribute(“listt”,list);
这样就实现模拟从action传递过来一个数据list,list集合中是4个实体对象
%>
接下来用iterator对数据进行遍历展示
<s:iterator value=”#request.listt” var=”em”>注意这里加一个request ,var 表示从集合中取出对象的小名,即取出来的对象叫em
<s:property value=”#em.eplId”/> 取对象中的id
<s:property value=”#em.username”/>再取对象中的username
</s:iterator>
显示的样式为:1 小明 2小红 3 小量 4小最
【1.9】看iterator还能提供什么实用功能
<s:iterator value=”#request.listt” var=”em”
begin=”0” 顾名思义从第几个数据开始
end=”2” 表示0,1,2,第三个结束
step=”2” 是隔几个跳一下,注意使用step的时候,必须加begin,不加begin写多少都是无效的
status=”st” 用来帮助标注该行的状态问题,如迭代到第几个了,当前元素索引,以及是否是第一个元素,最后一个元素
>
后面对st做判断,即可以在iterator中嵌套一个判断
<s:if test=”#st.index%2==0”> #st.index获取当前是第几行
<br> 即#st.index%2==0如果是偶数行,则换行
</s:if>
当前行号: <s:property value=”#st.index”/>
是否是第一条:<s:property value=”#st.first”/> 返回当前是否是第一个元素,如果是则为true,不是为false
是否是最后一条<s:property value=”#st.last”/>返回最后一个元素
计数走到第几个(行号+1)<s:property value=”#st.count”/>当前迭代到了第几个元素
是否是奇数行<s:property value=”#st.odd”/>当前迭代是奇数行吗?返回true
是否是偶数行<s:property value=”#st.even”/>当前迭代是偶数行吗?返回true
<s:property value=”#em.eplId”/> 取对象中的id
<s:property value=”#em.username”/>再取对象中的username
</s:iterator>
</body>
从interator处对集合进行筛选,是通过集合中某个对象(Em)的属性值(此处为eplId)
<s:iterator value=”#request.listt.{?#this.eplId>2}” var=”em”>
<s:property value=”#em.eplId”/>
<s:property value=”#em.username”/>
</s:iterator>
上面可以是?也可以是$ 也可以是^