1.struts.xml中的内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC" -//Apache Software Foundation//DTD Struts Configuration 2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="GBK" /> //解决中文乱码问题
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>//允许静态方法的方法的访问,用值栈访问静态方法时需要设置
<include file="login.xml" />//可以把另外一个xml文件引用进来
<package name="default" namespace="/" extends="struts-default">//设置成开发模式,当修改xml时,不用重新部署项目就能生效
//namespace命名空间,是指访问的url中http://localhost:8080/项目名/ hell 中的
<default-action-ref name="hell"></default-action-ref>//解决当找不到action是,默认制定的action,通常用于设置主页跳转
<action name="hell">//在这里不配置class,它默认执行的是ActionSupports
<result>
/Hello.jsp
</result>
</action>
</package>
<!-- Add packages here -->
</struts>
<url-pattern>/*</url-pattern>:/代表根目录
2.struts的工作流程
3.namespace的解释
namespace名加上action名,namespace决定了action的访问路径,默认为"",可以接受所有路径的action(http://localhost:8080/……各种……/index(只要能区别出index的action名就可以了)),namespace可以写为/,或者/xxxx,或则/xx/yyy,对应的action访问路径为/index.action,/xxxx/index.action,或则/xx/yyy/index.action,namespace最好用模块来进行命名
4.action的相关
每次访问一个action的时候,action中的类会每次new一个新对象,这样就不会存在线程安全问题
开发的action类一般继承的都是ActionSupport这个类(普遍),应为这个类中有很多已经封装好的方法可以使用,当然也可以继承action,或则不继承直接写exculte方法,返回字符串,具体的试图的返回可以由用户自己定义的action来决定,具体的手段是根据返回的字符串找到对应的配置项,来决定试图的内容
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="front" extends="struts-default" namespace="/"> <action name="index" class="com.bjsxt.struts2.front.action.IndexAction1">//action类 <result name="success">/ActionIntroduction.jsp</result> </action> </package> </struts>
IndexAction1.java
package com.bjsxt.struts2.front.action; import com.opensymphony.xwork2.ActionSupport; public class IndexAction3 extends ActionSupport { @Override public String execute() { return "success"; } }
5.对于路径的问题
在jsp中用request.getContextRoot的方式拿到webapp的路径或则使用myeclipse经常用的指定basepath,如下
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"
%>
<base href="<%=basePath%>" />
6.关于方法的动态调用
inde.jps
<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"pageEncoding="GB18030"%>
<% String context = request.getContextPath(); %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030" /> <title>Insert title here</title> </head> <body> Action执行的时候并不一定要执行execute方法<br /> 可以在配置文件中配置Action的时候用method=来指定执行哪个方法 也可以在url地址中动态指定(动态方法调用DMI)(推荐)<br /> <a href="<%=context %>/user/userAdd">添加用户</a>//通过方法调用<a href="<%=context %>/user/user!add">添加用户</a>//通过动态方法调用 前者会产生太多的action,所以不推荐使用 </body> </html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="user" extends="struts-default" namespace="/user"> <action name="userAdd" class="com.bjsxt.struts2.user.action.UserAction" method="add"> <result>/user_add_success.jsp</result> </action>//通过方法调用
<action name="user" class="com.bjsxt.struts2.user.action.UserAction"> <result>/user_add_success.jsp</result> </action>//通过动态方法调用 </package> </struts>
7.Action wildcard对action的通配符
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="actions" extends="struts-default" namespace="/actions">
<action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
<result>/Student{1}_success.jsp</result>
</action>
<action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">//第一个*对应的是{1},第二个*对应的是{2}
<result>/{1}_{2}_success.jsp</result>
<!-- {0}_success.jsp -->
</action>
</package>
</struts>
8.用action中的属性进行接收参数,如下
前台传递参数时:http://localhost:8080/user/user?name="zhao"&age=25
struts2会把传递参数的值,根据key对应到action中的相应的属性中
UserAction.java
package com.bjsxt.struts2.user.action;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private String name;
private int age;
public String add() {
System.out.println("name=" + name);
System.out.println("age=" + age);
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
9.用DomainModel接收参数,会把队形的参数设置到action中对象变量的属性中,如下
前台传递参数时:http://localhost:8080/user/user?user.name="zhao"&user.age=25
DomainModel中的对象只有传值才会构造初始化这个对象,如果不传,也可以自己new 注意:要保持参数为空的构造方法
User.java
package com.bjsxt.struts2.user.model;
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
UserAction.java
package com.bjsxt.struts2.user.action;
import com.bjsxt.struts2.user.model.User;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
private User user;
public String add() {
System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
10.使用ModelDriven接收参数,自动将参数值设置到action中的对象属性的参数中,如下
前台传递参数时:http://localhost:8080/user/user?name="zhao"&age=25
UserAction.java
package com.bjsxt.struts2.user.action;
import com.bjsxt.struts2.user.model.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction extends ActionSupport implements ModelDriven<User>{
private User user = new User();
public String add() {
System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
11.struts.xml中的常量的配置,
如 <constant name="struts.devMode" value="true" />,在struts2-core-2.1.6.jar-->org.apache.struts2-->default.properies中的各种默认常量配置
12.简单的数据校验
UserAction.java
package com.bjsxt.struts2.user.action; import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport { private String name; public String add() { if(name == null || !name.equals("admin")) { this.addFieldError("name", "name is error"); this.addFieldError("name", "name is too long");
return ERROR;
} return SUCCESS; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
在前台jsp中的取出的方法:用struts标签取出,struts标签的位置struts2-core-2.1.6.jar-->META-INFO-->struts-tags.tld
引用方式<%@taglib uri="/struts-tags" prefix="s" %>
用ngl表达式
<s:fielderror fieldName="name" theme="simple"/>//在值栈中这种方式去取
<s:property value="errors.name[0]"/>
<s:property value="#attr"/>//在stack context中也就actioncontext中以#来取
<s:debug></s:debug>
值栈的结构
<s:debug></s:debug>中的内容分为两部分,一种是value stack 值栈,一种是stack context(actioncontext)
13.关于请求返回,Map类型:request、session,application,真实类型:httpservletrequest,httpsession,httpcontext 的引用
①第一种方式,通过map来获取
LoginAction.java
package com.bjsxt.struts2.user.action;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction1 extends ActionSupport {
private Map request;
private Map session;
private Map application;
public LoginAction1() {
request = (Map)ActionContext.getContext().get("request");//此处用了单例模式,这里的“request”就是value stack中的value name 如下图所示,同理getSession也是value stack中的session,getApplication,是value stack中的
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
}
public String execute() {
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return SUCCESS;
}
}
在前台直接用对应的内置对象,request,session,application去取就好,或则通过value stack用#去取
login.jsp
<?xml version="1.0" encoding="GB18030" ?> <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030" /> <title>Insert title here</title> </head> <body> User Login Success! <br /> <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />//通过内置对象去取,通过值栈去取<s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br /> <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %>
<s:property value="#attr.a1"/><br />
<s:property value="#attr.s1"/><br /> <s:property value="#attr.r1"/><br /> <s:debug></s:debug> <br /> </body> </html>
②第二种方式,通过真实的类型来获取
package com.bjsxt.struts2.user.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class LoginAction3 extends ActionSupport { private HttpServletRequest request; private HttpSession session; private ServletContext application; public LoginAction3() { request = ServletActionContext.getRequest(); session = request.getSession(); application = session.getServletContext(); } public String execute() { request.setAttribute("r1", "r1"); session.setAttribute("s1", "s1"); application.setAttribute("a1", "a1"); return SUCCESS; } }
14.依赖注入,和控制反转(依赖struts把对应的request和session,application进行注入,不自己主动去拿,控制反转,把控制权交给struts容器),示例如下:
①通过map的方式来获取
package com.bjsxt.struts2.user.action; import java.util.Map; import org.apache.struts2.interceptor.ApplicationAware; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {//这种注入实际是通过拦截器判断是否实现了对应的接口,来进行复制到对象的对象中,例如request,如果拦截器发现实现了RequestAware时,就会执行拦截器吧内容注入到request中 private Map<String, Object> request;//不需要自己去主动获取 private Map<String, Object> session; private Map<String, Object> application; //DI dependency injection //IoC inverse of control public String execute() { request.put("r1", "r1"); session.put("s1", "s1"); application.put("a1", "a1"); return SUCCESS; } @Override public void setRequest(Map<String, Object> request) { this.request = request; }@Override public void setSession(Map<String, Object> session) { this.session = session; }@Override public void setApplication(Map<String, Object> application) { this.application = application; } }
②通过真实的类型来获取
package com.bjsxt.struts2.user.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.interceptor.ServletRequestAware; import com.opensymphony.xwork2.ActionSupport; public class LoginAction4 extends ActionSupport implements ServletRequestAware { private HttpServletRequest request; private HttpSession session; private ServletContext application; public String execute() { request.setAttribute("r1", "r1"); session.setAttribute("s1", "s1"); application.setAttribute("a1", "a1"); return SUCCESS; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; this.session = request.getSession(); this.application = session.getServletContext(); } }
15.result的type
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="resultTypes" namespace="/r" extends="struts-default"> <action name="r1"> <result type="dispatcher">/r1.jsp</result> //服务器跳转相当于forward,只能跳转到jsp或则html</action> <action name="r2"> <result type="redirect">/r2.jsp</result> //客户端跳转,url地址会改变,只能跳转jsp或者html </action> <action name="r3"> <result type="chain">
<param name="actionName">r1</param>
<param name="namespace">/r1</param>//“/”代表namespace
</result>//action跳转
</action> <action name="r4"> <result type="redirectAction">r2</result>//action跳转</action> </package> </struts>
16.全局结果集
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="user" namespace="/user" extends="struts-default"> <global-results> <result name="mainpage">/main.jsp</result>// 全局结果集,把各个action需要访问的公共页面提取出来 </global-results> <action name="index"> <result>/index.jsp</result> </action> <action name="user" class="com.bjsxt.struts2.user.action.UserAction"> <result>/user_success.jsp</result> <result name="error">/user_error.jsp</result> </action> </package> <package name="admin" namespace="/admin" extends="user">//继承自user包,可以使用user包中的所有,在项目中,会把公共的例如错误页面写入到一个公共的包中,各个模块来继承 <action name="admin" class="com.bjsxt.struts2.user.action.AdminAction"> <result>/admin.jsp</result> </action> </package> </struts>
17.动态结果集
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="user" namespace="/user" extends="struts-default"> <action name="user" class="com.bjsxt.struts2.user.action.UserAction"> <result>${r}</result>//从值栈里取值</action> </package> </struts>
UserAction.java
package com.bjsxt.struts2.user.action; import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport { private int type; private String r; public String getR() { return r; } public void setR(String r) { this.r = r; } public int getType() { return type; } public void setType(int type) { this.type = type; } @Override public String execute() throws Exception { if(type == 1) r="/user_success.jsp"; else if (type == 2) r="/user_error.jsp"; return "success"; } }
18.关于带参数的结果集
如果在一个请求中,因为所有action共享一个值栈,所以从值栈中取参数,用来传递,若用redirect进行客户端跳转时,因为是另外
一个值栈,所以在jsp向后台传递参数时(这个参数是从上一个action中取出来的,放到xml中进行传递),要从stack context中来取
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="user" namespace="/user" extends="struts-default"> <action name="user" class="com.bjsxt.struts2.user.action.UserAction"> <result type="redirect">/user_success.jsp?t=${type}</result> </action> </package> </struts>
user_success.jsp
<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>UserSuccess</title>
</head>
<body>
User Success!
from valuestack: <s:property value="t"/><br/>//取不出
from actioncontext: <s:property value="#parameters.t"/>//可以取出
<s:debug></s:debug>
</body>
</html>
19.ognl表达式总结
<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>OGNL表达式语言学习</title>
</head>
<body>
<ol>
<li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li>
<li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:property value="user[age]"/>--%></li>
<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>
<li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
<hr />
<li>访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li>
<li>访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li>
<li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>
<hr />
<li>访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li>
<hr />
<li>访问List:<s:property value="users"/></li>
<li>访问List中某个元素:<s:property value="users[1]"/></li>
<li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>访问Set:<s:property value="dogs"/></li>
<li>访问Set中某个元素:<s:property value="dogs[1]"/></li>
<li>访问Map:<s:property value="dogMap"/></li>
<li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
<hr />
<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>
<li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li>//^代表开头
<li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li>//$代表结尾
<li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
<hr />
<li>[]:<s:property value="[0].username"/></li>//[0]代表栈底到栈顶的所有东西
</ol>
<s:debug></s:debug>
</body>
</html>
20.struts标签
<?xml version="1.0" encoding="GB18030" ?>
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
<title>Struts-Tagsѧϰ</title>
</head>
<body>
<ol>
<li>property: <s:property value="username"/> </li>
<li>property 取值为字符串: <s:property value="'username'"/> </li>
<li>property 设定默认值: <s:property value="admin" default="管理员"/> </li>
<li>property 设定HTML: <s:property value="'<hr/>'" escape="false"/> </li>
<hr />
<li>set 设定adminName值(默认为request 和 ActionContext): <s:set var="adminName" value="username" /></li>
<li>set 从request取值: <s:property value="#request.adminName" /></li>
<li>set 从ActionContext取值: <s:property value="#adminName" /></li>
<%--<li>set 设定范围: <s:set name="adminPassword" value="password" scope="page"/></li>
<li>set 从相应范围取值: <%=pageContext.getAttribute("adminPassword") %></li>
--%>
<li>set 设定var,范围为ActionContext: <s:set var="adminPassword" value="password" scope="session"/></li>
<li>set 使用#取值: <s:property value="#adminPassword"/> </li>
<li>set 从相应范围取值: <s:property value="#session.adminPassword"/> </li>
<hr />
<%--<li>push:<s:set name="myDog" value="new com.bjsxt.struts2.ognl.Dog('oudy')"></s:set></li>
<li>
push:<s:push value="#myDog">
<s:property value="name"/>
</s:push>
</li>
<li>push: <s:property value="name"/></li>
--%>
<hr />
<li>bean ֨定义bean,并使用param来设定新的属性值:
<s:bean name="com.bjsxt.struts2.tags.Dog" >
<s:param name="name" value="'pp'"></s:param>
<s:property value="name"/>
</s:bean>
</li>
<li>bean查看debug情况:
<s:bean name="com.bjsxt.struts2.tags.Dog" var="myDog">
<s:param name="name" value="'oudy'"></s:param>
</s:bean>
拿出值:<s:property value="#myDog.name"/>
</li>
<hr />
<li>include _include1.html 包含静态英文文件
<s:include value="/_include1.html"></s:include>
</li>
<li>include _include2.html 包含静态中文文件
<s:include value="/_include2.html"></s:include>
</li>
<li>include _include1.html 包含静态英文文件,说明%用法
<s:set var="incPage" value="%{'/_include1.html'}" />
<s:include value="%{#incPage}"></s:include>//%{}强制将包裹的内容转化成ognl表达式
</li>
<hr />
<li>if elseif else:
age = <s:property value="#parameters.age[0]" /> <br />
<s:set var="age" value="#parameters.age[0]" />
<s:if test="#age < 0">wrong age!</s:if>
<s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>
<s:else>yeah!</s:else><br />
<s:if test="#parameters.aaa == null">null</s:if>
</li>
<hr />
<li>遍历集合:<br />
<s:iterator value="{1, 2, 3}" >
<s:property/> |
</s:iterator>
</li>
<li>自定义变量:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
<s:property value="#x.toUpperCase()"/> |
</s:iterator>
</li>
<li>ʹ使用status:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
<s:property/> |
遍历过的元素总和:<s:property value="#status.count"/> |
遍历过的元素索引:<s:property value="#status.index"/> |
当前是偶数?:<s:property value="#status.even"/> |
当前是奇数?:<s:property value="#status.odd"/> |
是第一个元素吗?:<s:property value="#status.first"/> |
是组后一个元素吗?:<s:property value="#status.last"/>
<br />
</s:iterator>
</li>
<li>
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" >
<s:property value="key"/> | <s:property value="value"/> <br />
</s:iterator>
</li>
<li>
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
</li>
<li>
<s:fielderror fieldName="fielderror.test" theme="simple"></s:fielderror>
</li>
</ol>
</body>
</html>
21.关于struts的ui
自己定义自己的theme
1.css(覆盖struts原来的css)
2.覆盖单个文件
3.定义自己的theme
4.实战:
a)把所有的主题定义为simple
b)fielderror特殊处理
c)自己控制器他标签的展现
22.声明式异常处理
只要遇到异常就往外抛throw,知道struts接到这个异常,实际实现原理是通过拦截器实现的
struts.xm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="bbs2009_default" extends="struts-default">
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> //针对所有的配法
</global-exception-mappings>
</package>
<package name="admin" namespace="/admin" extends="bbs2009_default" >
<action name="index">
<result>/admin/index.html</result>
</action>
<action name="*-*" class="com.bjsxt.bbs2009.action.{1}Action" method="{2}">
<result>/admin/{1}-{2}.jsp</result>
<result name="input">/admin/{1}-{2}.jsp</result>
<!-- <exception-mapping result="error" exception="java.sql.SQLException" /> //针对具体的配法
<result name="error">/error.jsp</result> -->
</action>
</package>
</struts>
23.拦截器的执行流程
读源码,debug单线跟踪,可以在eclipse的这一块观察方法调用顺序,从下往上的顺序看
24.自定义拦截器(不重要,基本不用,了解),关于角色的可以用框架 spring security来实现
模仿它原来的拦截器定义方法,自己加一个
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="test" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="my" class="com.bjsxt.interceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="test" class="com.bjsxt.action.TestAction">
<result>/test.jsp</result>
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
MyInterceptor.java
package com.bjsxt.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void destroy() {
// TODO Auto-generated method stub
}
public void init() {
// TODO Auto-generated method stub
}
public String intercept(ActionInvocation invocation) throws Exception {
long start = System.currentTimeMillis();
String r = invocation.invoke();
long end = System.currentTimeMillis();
System.out.println("action time = " + (end - start));
return r;
}
}
25.Token拦截器
原理是:在客户端和服务器端生成一段字符串,当字符串对应起来允许提交,对应不起来不允许提交
拦截器所在jar包的地址:struts2-core-2.1.6.jar --> struts-default.xml --> token
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="test" namespace="/" extends="struts-default">
<action name="input" class="com.bjsxt.action.InputAction">
<result>/input.jsp</result>
</action>
<action name="user" class="com.bjsxt.action.UserAction">
<result>/addOK.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token"></interceptor-ref>
<result name="invalid.token">/error.jsp</result>//返回的result字符串是invalid.token
</action>
</package>
</struts>
26.关于所传数据的类型转换
①关于struts的默认转换
1)对于date类型:例如传入url:http://localhost:8080/项目/test/?d=1991-01-08
在jsp页面接收传入的值:<s:date name = "d" formate="yyyy/MM/dd HH:mm:ss">
2)对list类型或则set的的转换:例如传入的url:http://localhost:8080/项目/test/?interests=math&interests=english
3)对于map的类型:例如传入的url:http://localhost:8080/项目/test/?users['a']=usera &users['a']=userb //'a'和'b'是key,usera和userb是value
TestAction.java
package com.bjsxt.action;
import java.awt.Point;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport {
private String name;
private int age;
private Date d;
List<String> interests;
Set<String> interests;
Map<String, String> users;
Point p;
List<Point> ps;
Map<String, Point> points;
@Override
public String execute() throws Exception {
return super.execute();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getD() {
return d;
}
public void setD(Date d) {
this.d = d;
}
public Set<String> getInterests() {
return interests;
}
public void setInterests(Set<String> interests) {
this.interests = interests;
}
public Map<String, String> getUsers() {
return users;
}
public void setUsers(Map<String, String> users) {
this.users = users;
}
public Point getP() {
return p;
}
public void setP(Point p) {
this.p = p;
}
public List<Point> getPs() {
return ps;
}
public void setPs(List<Point> ps) {
this.ps = ps;
}
public Map<String, Point> getPoints() {
return points;
}
public void setPoints(Map<String, Point> points) {
this.points = points;
}
}
test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Type Conversion</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
name:<s:property value="name"/><br/>
age:<s:property value="age"/><br/>//int类型
date:<s:property value="d"/><br/>//日期类型
<s:date name="d" format="yyyy/MM/dd HH:mm:ss"/><br/>//时间类型
<s:property value="interests"/><br/>//list或set类型
<s:property value="users"/><br/>//map类型
<s:property value="p"/><br/>
<s:property value="ps"/><br/>
points:<s:property value="points"/><br/>
</body>
</html>
②关于struts的自定义转换器
第一种写法:
publicclass MyPointConverter extends DefaultTypeConverter{
@Override
publicObject convertValue(Object value, Class toType) {
if(toType == Point.class) {
Point p = new Point();
String[] strs = (String[])value;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;
}
if(toType == String.class) {
return value.toString();
}
returnsuper.convertValue(value, toType);
}
}
第二种写法:
publicclass MyPointConverter extends StrutsTypeConverter{
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
Point p = new Point();
String[] strs = (String[])values;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;
}
@Override
publicString convertToString(Map context, Object o) {
// TODO Auto-generated method stub
return o.toString();
}
}
c)三种注册方式:
i.局部:XXXAction-conversion.properties
1.p(属性名称) = converter
ii.全局:xwork-conversion.properties
1.com.xxx.XXX(类名)= converter
iii.Annotation
d)如果遇到非常麻烦的映射转换
i.request.setAttribute();
ii.session