struts2的学习笔记

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

猜你喜欢

转载自blog.csdn.net/yuwenlanleng/article/details/84633132