(八)Struts标签基础(一)
一、Struts标签分类
二、标签的使用
2.1 标签的主题
- 主题的设置与struts.xml中的常量<constant name="struts.ui.theme" value="xhtml" /> 决定。
- 每个主题都会对一些标签产生作用,而这些作用被定义在一些文件文件里,比如
checkbox.ftl这个文件定义的是对checkbox标签产生作用的语法。
- 主题共有以下几种(版本为struts2-core-2.3.14.jar):
路径为:struts2-core-2.3.14.jar包里的
2.1.1 默认主题即template.xhtml , 会给标签自动添加一些属性或者子标签,可能打乱我们设计好的布局
<body>
<pre>
<h3>默认主题</h3>
<table border="1">
<tr>
<td>用户名</td>
<td> <s:textfield></s:textfield> </td>
</tr>
</table>
</pre>
</body>
- 我们原本的设计是这个表格一共一行且只有两个空格, 但是结果为:
- 出现这种情况是因为,template.xhtml这个主题会自动帮标签添加一些属性或子标签,查看源代码可知产生了td和tr子标签:
2.1.2 simple主题(最常用),额外添加的标签很少,不会对我们的布局产生大的影响。
- 在struts.xml中设置常量<constant name="struts.ui.theme" value="simple" />
index.jsp
<body>
<pre>
<h3>默认主题</h3>
<table border="1">
<tr>
<td>用户名</td>
<td> <s:textfield></s:textfield> </td>
</tr>
</table>
</pre>
</body>
查看源码:
- 对比我们的代码,文本框只添加了name属性
- 注意:在编写页面标签的时候,最好先把主题设置为simple主题,否则在布局的时候会很麻烦。
2.1.3 定制主题
- 步骤:
- 在src目录下新建一个文件夹,叫template (template名不能改成别的)
- 在template中在新建一个文件夹,名字自定义。
- 在自定义的文件夹中,将要修改的控制的ftl文件拷贝,进行修改。比如我们定制的主题中有对文本输入标签进行设定,那么我们就可以到simple这个主题里找到text.ftl这个文件(注意:text.ftl这个文件主题系统会自动作用在文本框里,如果换成别的名字则无法起作用),然后拷贝到我们自定义的文件夹里,再对text.ftl这个文件进行修改。
- 把text.ftl中需要添加的文件添加进来,text.ftl需要以下四个文件,然后在simple主题中找到这四个文件然后拷贝到自定义文件夹里即可。
- 修改text.ftl
红框内的内容是我们添加的css属性。
- 最后在标签中应用此主题,<s:textfield theme="self"></s:textfield> //self为tempalte包的主题包名,因为这里我们只定义了一个标签的主题,如果我们在在self自定义主题包里对大量标签进行了主题设定,那么我不必每个标签都使用theme属性来引入主题,只需要struts.xml中设置常量<constant name="struts.ui.theme" value="self" /> 即可。
结果:
可知标签主题已经变成我们自定义的了。
2.2 表单标签
2.2.1 为什么要使用表单标签?(struts表单标签和input标签的区别)
- struts表单标签可以与Action中的属性进行绑定,可以实现属性值到控件的Value值回填的操作。
- 示例:
- index.jsp:
<body>
<a href="<%=path%>/tag/form">表单标签</a>
</body>
- struts.xml
<struts> <constant name="struts.i18n.encoding" value="UTF-8"></constant>
<constant name="struts.multipart.maxSize" value="209715200"></constant>
<constant name="struts.action.extension" value="action,,"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.reload" value="true"></constant>
<constant name="struts.ui.theme" value="simple" />
<constant name="struts.configuration.xml.reload" value="true"></constant>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<constant name="struts.handle.exception" value="true"></constant> <package name="default" namespace="/tag" extends="struts-default">
<action name="form" class="tag.FromAction">
<result name="formjsp">/tag/form.jsp</result>
</action>
</package>
</struts>
FromAction .java
package tag; public class FromAction {
private String textName; public String getTextName() {
return textName;
} public void setTextName(String textName) {
this.textName = textName;
} public String execute(){ this.textName="Action对成员变量textNam赋值后会自动回填到表单中";
return "formjsp";
} }
- form.jsp
<body>
<pre>
<s:textfield name="textName"></s:textfield> </pre>
</body>
结果:
- 由结果可知,我们在Action中设置了一个成员变量textName,而这个成员变量名和<s:textfield name="textName"></s:textfield>是一样的,所以当我们在Action中对textName进行赋值的时候,struts会自动把值回填到<s:textfield name="textName"></s:textfield>标签里。 而如果在input标签中要实现数据的回填,则要在servlet中把值存放在作用域中,然后在jsp页面里用el表达式显示出来才行。
- input标签实现数据回填:
把值存放在作用域中 :request.setAttribute("属性", "input标签实现数据回填");
在jsp页面中把值取出来并显示: <input type="text" value="${requestScope.属性}"/>或者 <input type="text" value="<s:property value="#request.属性"/>"/>(request.setAttribute会吧属性放在广义值栈中的非狭义值栈的位置,所以需要用#来取值)。
2.1.2 struts表单标签的分类
- 文本框标签:<s:textfield name="textName"></s:textfield> name属性用来与Action中的成员变量绑定,请查看上例。
- 文本域标签:<s:textarea name="remark"></s:textarea>
- 密码框标签:<s:password name="passWd"></s:password>
- 静态单选框_1 :
<tr>
<td>静态单选框:</td>
<td>
<s:radio list="{'男','女'}" name="sex_1"></s:radio></td>
</tr>静态单选框中的list属性是必填的,list里的{}是OGNL表达式,意思是定义一个集合,本题中{'男','女'}意思是定义一个集合且这个集合中有两个string值。且list中集合有几个值那么就有几个单选按钮。如下图,每个单选按钮的值对应着集合中的值,如右下图。
- 静态单选框_2 :单选框的值由我们来设置,而不是静态单选框_1 由集合的值来定义。这里用的是OGNL表达式中的“#{}” 表示定义一个MAP集合。
<tr>
<td>静态单选框_2:</td>
<td><s:radio list="#{1:'男',0:'女'}" name="sex_1" ></s:radio></td>
</tr>
map集合中的1代表按钮value=“1”,表示如果用户选择的是“男”这个按钮,提交到后台的数据是“1” ,另一个按钮也是如此,查看源码:
- 单选框使用:
在JSP页面中创建单选按钮radio的方法:
<s:radio list="#{'1':'先生','0':'女士'}" name="gender" value="1"/>
其中list中的键值对表示所有的选项,value表示设置的默认值,如果这个默认值是从后台传过来的,可以这样设置:
<s:radio list="#{'1':'先生','0':'女士'}" name="gender" value="gender.id"/>
当list属性为Action传过来的Map时 可以自动显示为key-value形式
<s:radio list="%{map}" name="gender" value="gender.id "/>
当list属性为Action传过来的List<Gender>时 需要添加 listKey listValue属性 listKey对应提交到数据库中的值 listValue对应显示的文本
<s:radio list="%{list}" name="gender" value="gender.id" listKey="id" listValue="genderText""/>
- 动态单选框_1: 按钮value是从数据库或者其他地方获取的。
- 示例:从数据库中读取值。
A、 设计数据库并插入数据:
B、 加载数据库驱动jar包,使用数据库开源工具包(ommons-dbutils-1.3.jar),可以帮助我们快速操作数据库,编写操作数据库的工具类。
B1. 编写工具类,获取数据库的连接Connection conn,DBUtil.java :
package DBUtil; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class DBUtil {
private static final String DRIVER="com.mysql.jdbc.Driver";
private static final String USER="root";
private static final String PASSWD="";
private static final String URL="jdbc:mysql://127.0.0.1:3306/user?useUnicode=true&characterEncoding=UTF-8"; static{
try {
Class.forName(DRIVER);
} catch (Exception e) { throw new RuntimeException("无法加载驱动包");
}
} public static Connection getConn(){
Connection conn=null;
try {
conn= DriverManager.getConnection(URL,USER,PASSWD);
} catch (SQLException e) {
e.printStackTrace();
} return conn;
}
}
B2. 使用数据库开源工具包(ommons-dbutils-1.3.jar),这个包的类提供了快速增删改查方法的实现。FormAction.java
package tag; import java.util.List; import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler; import com.opensymphony.xwork2.ActionContext; import DBUtil.DBUtil;
import actionUtil.BaseAction;
import bean.UserBean; public class FromAction extends BaseAction{
/**
* QueryRunner类为数据库开源工具包(ommons-dbutils-1.3.jar)封装的类,
* 这个类实现了快速对数据库操作的方法。
* 步骤:
* 确认sql语句确定相应的方法,本题中select * 查询结果应该是一个集合。所以应该用QueryRunner的query()方法,
* 而query()方法里的三个参数为“Connection conn,String sql,ResultSetHandler<T> t”其中ResultSetHandler
* 是一个接口,我们往query()方法里填的参数不可能是接口而只能是其实现类,其中ResultSetHandler<T>的实现类BeanListHandler<T>类
* 是本题中需要的类,把这个类的对象加到query()方法里,这个方法将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里,也就是说我们
* 此时还需要创建一个javaBean类,这个类的成员属性(要有getset方法)要跟数据库中的列名一致。
*
*/ public String execute() throws Exception{
ActionContext actionContext=ActionContext.getContext(); String sql="select * from user order by userId";
QueryRunner query=new QueryRunner();
List<UserBean> list=query.query(DBUtil.getConn(), sql, new BeanListHandler<UserBean>(UserBean.class));
actionContext.put("list", list); return "formjsp";
} }
- 补充:ResultSetHandler的各个实现类:
ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。//重点
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。//重点
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
ScalarHandler:将结果集第一行的某一列放到某个对象中。//重点
B3. 在jsp页面把值取出来 from.jsp
<tr>
<td>静态单选框_2:</td>
<td><s:radio list="#list" name="sex_1" listKey="userId" listValue="userName"></s:radio></td>
</tr>
- list="#list" 表示往非广义值栈里取值为list的属性值(此时list存放的是javaBean对象的地址,所以取出来的也是地址),listValue="userName" 表示标签的属性value为javaBean对象的userName属性,
listKey="userId" 表单当用户选中某个选项的时候返回到后台的值。
结果:
参考刚才数据库里的数据
- 动态单选框_2: 按钮value是从数据库或者其他地方获取的。(与动态单选框_1类似)
- 在上例中,把DBUtil.java 文件修改如下(只是把上例的list转为Map):
package tag; import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler; import com.opensymphony.xwork2.ActionContext; import DBUtil.DBUtil;
import actionUtil.BaseAction;
import bean.UserBean; public class FromAction extends BaseAction{
/**
* QueryRunner类为数据库开源工具包(ommons-dbutils-1.3.jar)封装的类,
* 这个类实现了快速对数据库操作的方法。
* 步骤:
* 确认sql语句确定相应的方法,本题中select * 查询结果应该是一个集合。所以应该用QueryRunner的query()方法,
* 而query()方法里的三个参数为“Connection conn,String sql,ResultSetHandler<T> t”其中ResultSetHandler
* 是一个接口,我们往query()方法里填的参数不可能是接口而只能是其实现类,其中ResultSetHandler<T>的实现类BeanListHandler<T>类
* 是本题中需要的类,把这个类的对象加到query()方法里,这个方法将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里,也就是说我们
* 此时还需要创建一个javaBean类,这个类的成员属性(要有getset方法)要跟数据库中的列名一致。
*
*/ public String execute() throws Exception{
ActionContext actionContext=ActionContext.getContext(); String sql="select * from user order by userId";
QueryRunner query=new QueryRunner();
List<UserBean> list=query.query(DBUtil.getConn(), sql, new BeanListHandler<UserBean>(UserBean.class)); Map<String,String> userMap=new HashMap<String, String>(); if(list!=null){
/**
* 把List转换为Map
*/
for(UserBean user:list){
String userName=user.getUserName();
String userId=user.getUserId();
userMap.put(userId, userName); }
}
actionContext.put("userMap", userMap); return "formjsp";
} }form.jsp:
- 在上例中,把DBUtil.java 文件修改如下(只是把上例的list转为Map):
<tr>
<td>静态单选框_2:</td>
<td><s:radio list="#userMap" name="sex_1" ></s:radio></td>
</tr>
- 此时就不用添加listValue和listKey属性了,因为Map就是键值对。
- 下拉框标签:
- 下拉框也有动态下拉框如果需要的话,可以参考动态单选框_1/动态单选框_2,但是下拉框一般是固定的值,没必要动态获取。
- 下拉框标签:
<tr>
<td>下拉框</td>
<td><s:select list="{'福建','山东','河南'}" name="privince" headerKey="none" headerValue="---请选择---"></s:select></td>
</tr>
- 下拉框分组:
<tr>
<td>下拉框分组</td>
<td>
<s:select list="{'福建','山东','河南'}" name="privince" headerKey="none"
headerValue="---请选择---">
<s:optgroup list="#{1:'泉州',2:'莆田',3:'福州'}" label="福建" ></s:optgroup>
</s:select>
</td>
</tr>
<s:optgroup >标签只能放在<s:select>标签里,且list只能用"#{}"这个OGNL表达式也就是一定要用Map,否则错误。
label标签不可选定。
- 复选框标签和复选框分组标签:
本例的文件与动态单选框_1中的文件相同,只有最后的form.jsp页面改成下面
<tr>
<td>复选框:</td>
<td><s:checkbox name="is_check" value="true"></s:checkbox></td>
</tr> <tr>
<td>复选框分组:</td>
<td><s:checkboxlist list="#userMap" name="group"></s:checkboxlist></td>
</tr>
结果:
- 其中list="userMap"是数据库的数据封装为Map对象,而且<s:checkboxlist>中的list和name属性一定要写,name如果没写ftl文件会报name属性未定义这个错误。
<s:checkboxlist>中的list如果是List集合,那么就要加listValue和listKey属性。
隐藏域和文件域名标签
<tr>
<td>隐藏域</td>
<td><s:hidden name="userId"></s:hidden ></td>
</tr>
<tr>
<td>文本域</td>
<td><s:file name="userface"></s:file ></td>
</tr>
结果:
- 表单标签:
<s:form name="" id="" action="" method=""></form>
- 按钮标签:
- struts中没有普通按钮标签。
- 上下下拉框(使用这个标签要在<head>标签里定义<s:head />标签,这个标签用于引入上下下拉框等标签所需的脚本文件)
<tr>
<td>上下下拉框</td>
<td><s:updownselect list="{'1','2','3'}" name="text" cssStyle="width:60px"
allowMoveDown="true" allowMoveUp="true" allowSelectAll="true" moveDownLabel="向下移动" moveUpLabel="向上移动" selectAllLabel="全选"
></s:updownselect></td>
</tr>
- 用法类似动态单选框_1和动态单选框_2
- 选项传输下拉框(1. 使用这个标签要在<head>标签里定义<s:head />标签,这个标签用于引入上下下拉框等标签所需的脚本文件 2. 使用这个标签的时候不能用submit按钮提交,否则后台取值的时候会全部取到而不是只取用户选定的,只能通过定义普通按钮然后这个按钮触发一个javaScript脚本,在脚本里定义一个submit()方法提交)
- 组合框标签(1.使用这个标签要在<head>标签里定义<s:head />标签,这个标签用于引入上下下拉框等标签所需的脚本文件 2. 使用这个标签的时候不能用submit按钮提交,否则后台取值的时候会全部取到而不是只取用户选定的,只能通过定义普通按钮然后这个按钮触发一个javaScript脚本,在脚本里定义一个submit()方法提交)
(八)Struts标签基础(一)的更多相关文章
- (九)Struts标签基础(二)
2.3 非表单标签 2.3.1 <s:actionerror>标签, this.addActionError("错误信息1"); //使用addActionErro ...
- 2017-2018-2 20155228 《网络对抗技术》 实验八:Web基础
2017-2018-2 20155228 <网络对抗技术> 实验八:Web基础 1. 实践内容 1.1 Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET ...
- 20145203盖泽双 《网络对抗技术》实践八:Web基础
20145203盖泽双 <网络对抗技术>实践八:Web基础 1.实践目标 (1)编写Web前端--含有表单的HTML代码. (2)编写Web前端--javascipt验证用户名.密码的代码 ...
- 2017-2018-2 20155231《网络对抗技术》实验八: WEB基础实验
2017-2018-2 20155231<网络对抗技术>实验八:Web基础 实验要求: Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与P ...
- struts 标签<s:ierator>的简单使用说明
struts 标签<s:ierator>的简单使用说明,只显示<s:ierator> 的前6条数据 <s:iterator value="lstVisitor& ...
- 转:Struts标签checkbox使用总结(默认选择设置)
在使用struts标签html:checkbox 的时候,如何让checkbox框默认是选中的,一般情况 下都是当formbean里面该property的值和标签上value给定的值相等的时候,生成的 ...
- Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用
我之前虽然会用,但是一直分不清彼此之间有什么区别,所以查找资料,将它们进行整合区分,加深了解, 一 介绍 1.Struts2的作用 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的 ...
- [转]Struts标签库详解
本文转自:http://hi.baidu.com/xzkcz/blog/item/5cf9f91f01beb9f4e0fe0bd4.html Struts提供了五个标签库,即:HTML.Bean. ...
- JSTL、EL、ONGL、Struts标签的区别与使用
一.JSTL 来源 我们使用JSP开发信息展现非常方便,也可嵌入java代码用来实现相关逻辑,但同样带来了很多问题: jsp维护难度增加 出事提示不明确,不容易提示 分工不明确等 解决上面的问题可以 ...
随机推荐
- 二维背包---P1509 找啊找啊找GF
P1509 找啊找啊找GF 题解 很明显这是一道二维背包题目 如果一个dp数组做不了,那么我们就再来一个dp数组 题目要求,花费不超过 m ,消耗人品不超过 r ,泡到尽量多的妹子,时间尽量少 f ...
- AT1357 n^p mod m(洛谷)
题意翻译 求 n^p mod m 的值 输入格式 一行,为整数 n,m,p(注意顺序) 输出格式 一行,为 n^p mod m 的值 数据说明 对于100%的数据 1≤n,m≤10^91≤n,m≤10 ...
- mongo 导入import 导出 exprot操作
.mongo export导出 /mongoexport /h [ip地址] /port [端口] /u [用户名] /p [密码] /d [数据库] -c [表名] /q [查询语句] /o [保 ...
- 机器学习 - 算法 - PCA 主成分分析
PCA 主成分分析 原理概述 用途 - 降维中最常用的手段 目标 - 提取最有价值的信息( 基于方差 ) 问题 - 降维后的数据的意义 ? 所需数学基础概念 向量的表示 基变换 协方差矩阵 协方差 优 ...
- Spring走向注解驱动编程
SpringFramework的两大核心,IOC(Inversion of control)控制反转和DI(Dependency Inject)依赖注入,其推崇的理念是应用系统不应以java代码的方式 ...
- 使用 Sublime + PlantUML 高效地画图
转自 http://www.jianshu.com/p/e92a52770832
- Python(1)自动发送邮件
python发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是python自带的,只需import即可使用.smtplib模块主要负责发送邮件,email模块主要负责构造邮件. sm ...
- MySQL 全局锁和表锁
根据加锁的范围,MySQL 里面的锁大致可以分成全局锁,表级锁,行锁. 行锁已经在前面几篇文章说过 1. 全局锁 全局锁就是对整个数据库实例加锁.MySQL 提供了一个加全局读锁的方法,命令是Flus ...
- ORACLE创建表空间和用户,并分配权限
注意:如果是创建新的库,首先要先创建表空间,之后才可以创建用户:1.//创建临时表空间 create tablespace NCPZS_DATA datafile '/home/soft/oracle ...
- mac清除launchpad 应用程序和图标
打开launchpad显示所有的程序,有时候却无法删除一些应用图标和程序 用Spotlight(command+空格键),我们输入要删除的应用名称 我们按住Command再点回车, 搜索的结果就会在f ...