标签与属性范围
- Struts2.x.Spring MVC 都会提供有一些属于自己的标签,但是从实际开发中不怎么会去使用这些标签.
- 从标准mvc设计模式来讲,一个Action(Servlet功能一样)可以传递内容到JSP页面进行显示处理,往往会使用request属性范围完成,但是如果说在Struts2.x里面并且使用了struts2.x的标签.
- 定义Dept的vo类
package mao.shu.vo;
import java.io.Serializable;
public class Dept implements Serializable {
private int deptno;
private String dname;
private String loc;
public int getDeptno() {
return deptno;
}
//setter和getter方法
}
- 定义DeptAction类
package mao.shu.action;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import mao.shu.vo.Dept;
public class DeptAction extends ActionSupport {
private String msg;
private Dept dept;
public String getMsg() {
return msg;
}
public Dept getDept() {
return dept;
}
@Override
public String execute() throws Exception {
//Action类属性
this.msg = "DeptAction类属性:msg";
this.dept.setDeptno(10);
this.dept.setDname("DeptAction类属性:dept.dname");
this.dept.setLoc("DeptAction类属性:dept.loc");
//request属性范围
ServletActionContext.getRequest().setAttribute("info", "info--request属性范围");
Dept vo = new Dept();//request属性范围传递的dept
vo.setDeptno(99);
vo.setDname("request属性范围的dept.dname");
vo.setLoc("request属性范围的dept.loc");
ServletActionContext.getRequest().setAttribute("dept", vo);
return ActionSupport.SUCCESS;
}
}
- 此时两组内容一个是通过类中的属性设置的,另一个是通过request属性范围传递过去
- 在struts.xml文件中配置Action映射路径
<package name="root" namespace="/" extends="struts-default">
<action name="DeptAction" class="mao.shu.action.DeptAction">
<result type="success">/show.jsp</result>
</action>
</package>
- 定义dept_show.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1><s:property value="msg"/></h1>
<h1><s:property value="dept.deptno"/></h1>
<h1><s:property value="dept.dname"/></h1>
<h1><s:property value="dept.loc"/></h1>
<hr/>
<h1><s:property value="info"/></h1>
<h1><s:property value="vo.deptno"/></h1>
<h1><s:property value="vo.dname"/></h1>
<h1><s:property value="vo.loc"/></h1>
</body>
</html>
- 访问:http://localhost:8080/TagProject/DeptAction.action
- 发现只有DeptAction的类属性被显示出来,而request设置的属性没有被显示出来.
- 需要注意的问题是,在Struts2.x中所有的标签只能够输出Action中属性的内容,实际上它使用的是一种称为OGNL表达式语法完成的.所以如果要想使用OGNL进行访问.则需要在前缀加上"#request.属性"
- 修改show.jsp
<h1><s:property value="#request.info"/></h1>
<h1><s:property value="#request.vo.deptno"/></h1>
<h1><s:property value="#request.vo.dname"/></h1>
<h1><s:property value="#request.vo.loc"/></h1>
- 可以发现如果使用Struts2.x标签这么复杂,还不如直接使用El表达式即可
<h1>${info} </h1>
<h1>${vo.deptno} </h1>
<h1>${vo.dname} </h1>
<h1>${vo.loc} </h1>
非UI标签
- 所谓的非UI标签与表单的现实无关.实际上在标签之中是有好的处理模式存在的
- 格式化日期显示
- 有时候往往会通过Action传递Date型对象过去,此时有可能需要格式化显示处理;
- 编写DemoAction程序类
package mao.shu.action;
import java.util.Date;
import org.apache.struts2.ServletActionContext;
public class DemoAction extends ActionSupport {
@Override
public String execute() throws Exception {
ServletActionContext.getRequest().setAttribute("birthday", new Date());
return Action.SUCCESS;
}
}
- 在struts.xml文件配置该Action
<action name="DemoAction" class="mao.shu.action.DemoAction">
<result name="success">/show.jsp</result>
</action>
- 随后在demo_show.jsp页面中进行显示
<h1><s:property value="#request.birthday"/></h1>
- 但是直接输出的日期默认格式,可读性不是很强,所以就可以使用道struts2的日期标签
- 修改demo_show.jsp
<h1><s:date name="#request.birthday" format="yyyy-MM-dd HH:mm:SSS"/></h1>
- 这个时候发现有些标签挺灵活的.
- 文本显示:如果要进行国际化显示,所有页面中显示的数据也应该通过资源文件读取,所以在Struts2.x也可以通过标签读取资源文件信息.
- 定义struts.properties
struts.custom.properties=Messages
- 定义Messages.properties文件
mao.shu.info=我的姓名为:{0},年龄{1},性别{2}
-
如果要进行国际化的操作处理,那么一定是i18n的处理操作
-
在jsp页面中进行显示
<h1>
<s:i18n name="Messages">
<s:text name="mao.shu.info">
<s:param>xiemaoshu</s:param>
<s:param>22</s:param>
<s:param>男</s:param>
</s:text>
</s:i18n>
</h1>
- 迭代输出,只要是JSP的代码开发,那么一定要提供有迭代输出的操作标签.
- 准备出一个List集合,该集合中保存多个Dept对象
package mao.shu.action;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import mao.shu.vo.Dept;
public class DemoAction extends ActionSupport {
@Override
public String execute() throws Exception {
List<Dept> allDepts = new ArrayList<Dept>();
for(int x = 0; x < 10;x++){
Dept vo = new Dept();
vo.setDeptno(x);
vo.setDname("dname"+x);
vo.setLoc("loc"+x);
allDepts.add(vo);
}
ServletActionContext.getRequest().setAttribute("allDepts", allDepts);
return Action.SUCCESS;
}
}
- 在demo_show.jsp页面之中进行显示
<s:if test="#request.allDepts != null">
<s:iterator value="#request.allDepts" var="dept">
<li>deptno= <s:property value="deptno"/> dname= <s:property value="dname"/> loc= <s:property value="loc"/></li>
</s:iterator>
</s:if>
- 虽然使用以上的方法能够输出集合数据,但是struts2的<s:iterator>标签使用起来比较麻烦,如果直接使用EL表达式,代码会更加的简单
<s:if test="#request.allDepts != null">
<s:iterator value="#request.allDepts" var="dept">
<li>deptno= ${deptno} dname= ${dname } loc= ${loc }</li>
</s:iterator>
</s:if>
- 在使用<itetator>标签迭代时,都会自动将vo类中的属性取出单独保存在属性范围之中,所以可以方便的进行内容的取出但是从本质上来讲,更多情况下是不会这样使用.
UI标签
- 所有的UI标签就是实现界面显示处理,但是这种的显示处理模式不方便
- 观察UI问题
- 定义一个FormAction程序类,此时暂不处理任何操作
package mao.shu.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import mao.shu.vo.Dept;
public class FormAction extends ActionSupport {
@Override
public String execute() throws Exception {
return Action.SUCCESS;
}
}
- 在struts.xml文件中配置该Action的映射路径
</action>
<action name="FormAction" class="mao.shu.action.FormAction">
<result name="success">/form_show.jsp</result>
</action>
- 定义一个form_show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<base href="<%= basePath%>">
</head>
<body>
<s:form action="FormAction.action" method="post">
<s:textfield label="姓名" key="name"></s:textfield>
<s:submit>发送</s:submit>
</s:form>
</body>
</html>
- 查看执行后生成的页面源代码
-
如果按照以上的方式编写,生成的代码对于前端的开发不是很友好,如果不希望struts2自动生成样式,则可以使用
-
取消内置样式
-
只需要在标签中加入 theme=“simple” 即可取消默认样式
<s:form action="FormAction.action" method="post" theme="simple">
<s:textfield label="姓名" key="name" theme="simple"></s:textfield>
<s:submit value="发送"></s:submit>
</s:form>
-
实际上子UI标签里面,对于文本数据的显示是没有什么特点的,有特点的标签是针对于下拉列表框与复选框实现的
-
实现下拉列表框
- 在FormAction之中传递一个集合传递一个部门集合
package mao.shu.action;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import mao.shu.vo.Dept;
public class FormAction extends ActionSupport {
@Override
public String execute() throws Exception {
List<Dept> allDepts = new ArrayList<Dept>();
for(int x = 0; x < 10;x++){
Dept vo = new Dept();
vo.setDeptno(x);
vo.setDname("dname"+x);
vo.setLoc("loc"+x);
allDepts.add(vo);
}
ServletActionContext.getRequest().setAttribute("allDepts", allDepts);
return Action.SUCCESS;
}
}
- 如果使用UI标签来处,直接使用一个标签就能够生成了
<s:select list="#request.allDepts" listKey="deptno" listValue="dname"></s:select>
- 生成的页面源代码
- 生成复选框
<s:checkboxlist list="#request.allDepts" listKey="deptno" listValue="dname" name="dno"></s:checkboxlist>
- 生成的页面代码
- 虽然struts2的标签有些很好用,但是牺牲了自定义的前端开发很不值得.
- Action类中该如何接收复选框的参数
- 修改FormAction类,添加dno参数,并添加setter和getter方法
public class FormAction extends ActionSupport {
private int[] dno;//接收checkbox的提交参数
public int[] getDno() {
return dno;
}
public void setDno(int[] dno) {
this.dno = dno;
}
@Override
public String execute() throws Exception {
System.out.println(Arrays.toString(dno));
List<Dept> allDepts = new ArrayList<Dept>();
for(int x = 0; x < 10;x++){
Dept vo = new Dept();
vo.setDeptno(x);
vo.setDname("dname"+x);
vo.setLoc("loc"+x);
allDepts.add(vo);
}
ServletActionContext.getRequest().setAttribute("allDepts", allDepts);
return Action.SUCCESS;
}
}
- 后台输出
- 如果单值的接收,直接编写变量即可,如果是数组就是用数组,并且struts2支持自动类型转换.