Struts中的OGNL表达式语言1/Struts标签与OGNL表达式语言实例演练2/Struts2常用标签总结3

Struts中的OGNL表达式语言

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。
相对EL表达式,它提供了平时我们需要的一些功能,如:
l支持对象方法调用,如xxx.sayHello();                                                                                               
l支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@ java.lang.String@format('foo %s', 'bar')或@cn.csdn.Constant@APP_NAME;
l操作集合对象。
lOgnl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了 java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图 :
   
 当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
  
     
          访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象 :
      
   
       在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。
          大家注意:Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/>
 
  
 
           由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
        ${foo} //获得值栈中某个对象的foo属性
         如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
         application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用              ServletContext的getAttribute("username")。
        session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
         request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
        parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
        attr对象:用于按page->request->session->application顺序访问其属性。
  
      为何使用EL表达式能够访问valueStack中对象的属性?
    
原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
 public class StrutsRequestWrapper extends HttpServletRequestWrapper {
       public StrutsRequestWrapper(HttpServletRequest req) {
           super(req);
       }
       public Object getAttribute(String s) {
        ......
        ActionContext ctx = ActionContext.getContext();
        Object attribute = super.getAttribute(s);//先从request范围获取属性值
        if (ctx != null) {
            if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
               ......
               ValueStack stack = ctx.getValueStack();
               attribute = stack.findValue(s);
               ......
            }
        }
        return attribute;
    }
 }
  
     采用OGNL表达式创建List/Map集合对象:
       
如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。
使用如下代码直接生成一个List对象:
 <s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iterator value="#list" id="n">
<s:property value="n"/><br>
</s:iterator>
生成一个Map对象:
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<s:iterator value="#foobar" >
<s:property value="key"/>=<s:property value="value"/><br>
</s:iterator>
Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。如果没有设置该属性,则默认放置在OGNL Context中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
 
 
          采用OGNL表达式判断对象是否存在于集合中?
   
对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如下所示。
in表达式:
<s:if test="'foo' in {'foo','bar'}">
   在
</s:if>
<s:else>
   不在
</s:else>
not in表达式:
<s:if test="'foo' not in {'foo','bar'}">
   不在
</s:if>
<s:else>
   在
</s:else>
 
                  OGNL表达式的投影功能?
       
除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
?:获得所有符合逻辑的元素。
^:获得符合逻辑的第一个元素。
$:获得符合逻辑的最后一个元素。
例如代码:
<s:iterator value="books.{?#this.price > 35}">
      <s:property value="title" /> - $<s:property value="price" /><br>
</s:iterator>
在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。
public class BookAction extends ActionSupport {
private List<Book> books;
....
@Override
    public String execute() {
        books = new LinkedList<Book>();
        books.add(new Book("A735619678", "spring", 67));
books.add(new Book("B435555322", "ejb3.0",15));
}
}
 
     property标签:
 
property标签用于输出指定值:
<s:set name="name" value="'kk'" />
<s:property value="#name"/>
default:可选属性,如果需要输出的属性值为null,则显示该属性指定的值
escape:可选属性,指定是否格式化HTML代码。
value:可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。
id:可选属性,指定该元素的标识
 
     iterator标签:
   
iterator标签用于对集合进行迭代,这里的集合包含List、Set和数组。
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iterator value="#list" status="st">
<font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>>
<s:property /></font><br>
</s:iterator>
value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
id:可选属性,指定集合里元素的id。
status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法:
int getCount(),返回当前迭代了几个元素。
int getIndex(),返回当前迭代元素的索引。
boolean isEven(),返回当前被迭代元素的索引是否是偶数
boolean isOdd(),返回当前被迭代元素的索引是否是奇数
boolean isFirst(),返回当前被迭代元素是否是第一个元素。
boolean isLast(),返回当前被迭代元素是否是最后一个元素。
 
        if/elseif/else标签:
    
<s:set name="age" value="21" />
<s:if test="#age==23">
23
</s:if>
<s:elseif test="#age==21">
21
</s:elseif>
<s:else>
都不等
</s:else>
    
    url标签:
 
<s:url action="helloworld_add" namespace="/test"><s:param name="personid" value="23"/></s:url>
生成类似如下路径:
/struts/test/helloworld_add.action?personid=23
红色部分为内容路径。
当标签的属性值作为字符串类型处理时, “%”符号的用途是计算OGNL表达式的值。
  <s:set name="myurl" value="'http://www.foshanshop.net'"/>
   <s:url value="#myurl" /><br>
   <s:url value="%{#myurl}" />
输出结果:
#myurl
http://www.foshanshop.net
 
    表单标签_checkboxlist复选框:
  
如果集合为list
<s:checkboxlist name="list" list="{'Java','.Net','RoR','PHP'}" value="{'Java','.Net'}"/>
生成如下html代码:
<input type="checkbox" name="list" value="Java" checked="checked"/><label>Java</label>
<input type="checkbox" name="list" value=".Net" checked="checked"/><label>.Net</label>
<input type="checkbox" name="list" value="RoR"/><label>RoR</label>
<input type="checkbox" name="list" value="PHP"/><label>PHP</label>
如果集合为MAP
<s:checkboxlist name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value" value="{1,2,3}"/>
l生成如下html代码:
<input type="checkbox" name="map" value="1" checked="checked"/><label>瑜珈用品</label>
<input type="checkbox" name="map" value="2" checked="checked"/><label>户外用品</label>
<input type="checkbox" name="map" value="3" checked="checked"/><label>球类</label>
<input type="checkbox" name="map" value="4"/><label>自行车</label>
 
    表单标签_checkboxlist复选框:
 
如果集合里存放的是javabean
l <%
l  Person person1 = new Person(1,"第一个");
l  Person person2 = new Person(2,"第二个");
l  List<Person> list = new ArrayList<Person>();
l  list.add(person1);
l  list.add(person2);
l  request.setAttribute("persons",list);
l  %>
l<s:checkboxlist name="beans" list="#request.persons" listKey="personid" listValue="name"/>
l Personid和name为Person的属性
l生成如下html代码:
l<input type="checkbox" name=“beans" value="1"/><label>第一个</label>
l<input type="checkbox" name=“beans" value="2"/><label>第二个</label>
 
       表单标签_radio单选框:
 
  
该标签的使用和checkboxlist复选框相同。
l如果集合里存放的是javabean(personid和name为Person的属性)
l< s:radio name="beans" list="#request.persons" listKey="personid" listValue="name"/>
l生成如下html代码:
l<input type="radio" name="beans" id="beans1" value="1"/><label>第一个</label>
l<input type="radio" name="beans" id="beans2" value="2"/><label>第二个</label>
l如果集合为MAP
l<s:radio name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value“ value="1"/>
l生成如下html代码:
l<input type="radio" name="map" id="map1" value="1"/><label for="map1">瑜珈用品</label>
l<input type="radio" name="map" id="map2" value="2"/><label for="map2">户外用品</label>
l<input type="radio" name="map" id="map3" value="3"/><label for="map3">球类</label>
l<input type="radio" name="map" id="map4" value="4"/><label for="map4">自行车</label>
l如果集合为list
l<s:radio name="list" list="{'Java','.Net'}" value="'Java'"/>
l生成如下html代码:
l<input type="radio" name="list" checked="checked" value="Java"/><label>Java</label>
l<input type="radio" name="list" value=".Net"/><label>.Net</label>
 
     表单标签_select下拉选择框:
 
  
<s:select name="list" list="{'Java','.Net'}" value="'Java'"/>
<select name="list" id="list">
    <option value="Java" selected="selected">Java</option>
    <option value=".Net">.Net</option>
</select>
<s:select name="beans" list="#request.persons" listKey="personid" listValue="name"/>
<select name="beans" id="beans">
    <option value="1">第一个</option>
    <option value="2">第二个</option>
</select>
<s:select name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value" value="1"/>
<select name="map" id="map">
    <option value="1" selected="selected">瑜珈用品</option>
    <option value="2">户外用品</option>
    <option value="3">球类</option>
    <option value="4">自行车</option>
</select>
 
   <s:token />标签防止重复提交:
  
l<s:token />标签防止重复提交,用法如下:
l第一步:在表单中加入<s:token />
l<s:form action="helloworld_other" method="post" namespace="/test">
l  <s:textfield name="person.name"/><s:token/><s:submit/>
l  </s:form>
l 第二步:
l <action name="helloworld_*" class="cn.csdn.action.HelloWorldAction" method="{1}">
l        <interceptor-ref name="defaultStack" />
l         <interceptor-ref name="token" />
l         <result name="invalid.token">/WEB-INF/page/message. jsp</result> 
l         <result>/WEB-INF/page/result.jsp</result>
l </action>
l 以上配置加入了“token”拦截器和“invalid.token”结果,因为“token”拦截器在会话的token与请求的:
l严重: ParametersInterceptor - [setParameters]: Unexpected Extoken不一致时,将会直接返回“invalid.token”结果。
l在debug状态,控制台出现下面信息,是因为Action中并没有struts.token和struts.token.name属性,我们不用关心这个错误ception caught setting 'struts.token' on 'class xxx: Error setting expression 'struts.token' with value '[Ljava.lang.String;@39f16f'
l严重: ParametersInterceptor - [setParameters]: Unexpected Exception caught setting 'struts.token.nam 编程10000问  > 正文 订阅本分类信息

Struts标签与OGNL表达式语言实例演练

项目结构如图:


主要类文件如下:

     AdminAction.java

public class AdminAction extends ActionSupport{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Admin admin;
	
	
	public Admin getAdmin() {
		return admin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}

	public String Login(){
//        使用request存值
		ActionContext actionContext = ActionContext.getContext();
		actionContext.put("Lili", "你好!");
//		 使用session存值
		  actionContext.getSession().put("Jenny", "你好Jenny");
//		 使用application存值
		  actionContext.getApplication().put("Nike", "谢谢Nike");
//		 存入对象
//        使用request存值
		 actionContext.put("admin", admin);
//		 使用session存值
		  actionContext.getSession().put("admin", admin);
//		 使用application存值
		  actionContext.getApplication().put("admin", admin);
		  
		return "adminaction_login";
	}

	public String save(){
         System.out.println("保存成功!!!!!!");	
		
		return "adminaction_save";
	}
	public String delete(){
		System.out.println("删除成功!!!!!!");	
		
		return "adminaction_delete";
	}
	public String update(){
		System.out.println("修改成功!!!!!!");	
		
		return "adminaction_update";
	}
	public String find(){
		System.out.println("查询成功!!!!!!");	
		
		return "adminaction_find";
	}
	

}


Admin.java

public class Admin {
  private String userName;
  private String userPassword;
public String getUserName() {
	return userName;
}
public void setUserName(String userName) {
	this.userName = userName;
}
public String getUserPassword() {
	return userPassword;
}
public void setUserPassword(String userPassword) {
	this.userPassword = userPassword;
}
  
  
}
 
struts.xml
	<struts>
	    <package name="struts" namespace="/csdn" extends="struts-default" >
	        <!-- 
	         使用通配符进行测试!
	         -->
	         <action name="*_*" class="www.csdn.net.action.{1}" method="{2}">     
	         <result name="adminaction_loginError" type="dispatcher">/manager/ErrorNormal.jsp </result>
	         <result name="adminaction_login" type="dispatcher">/manager/Login.jsp </result>
	         <result name="adminaction_save" type="dispatcher">/manager/Save.jsp </result>
	         <result name="adminaction_delete" type="dispatcher">/manager/Delete.jsp </result>
	         <result name="adminaction_update" type="dispatcher">/manager/Update.jsp </result>
	         <result name="adminaction_find" type="dispatcher">/manager/Find.jsp </result>
	       </action>
	    </package>
	</struts>




index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
  <body style="text-align: center">    
  <h2>这是第一个使用structs2标签开发的应用测试实例!</h2>
  
    <s:form action="AdminAction_Login" namespace="/csdn" method="post">
      <s:textfield name="admin.userName" label="用户名:"></s:textfield>
      <s:password name="admin.userPassword" label="密码:"></s:password>
      <s:submit  value="登陆"></s:submit> 
      <s:reset value="重置"></s:reset>
     
    </s:form>
  </body>
</html>

主要实例演示:

    Login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'Login.jsp' starting page</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">
   <style type="text/css">
   .even{
      background-color:red;
    }
.odd{
      background-color:blue;
    }
   </style>

    
  </head>
  
  <body style="text-align: center">
  <<<<<---------------------------------------------------------------->>>>>
  <h2>这是第一个使用structs2标签和设置session属性对象开发的应用测试实例!</h2>
  <h3>${admin.userName}用户登陆成功!!!</h3><br/>
  <hr/>
  <h3>使用ongl标签输出存入不同作用域中的值:</h3>
  输出request作用域中存入的信息:
         <s:property value = "#request.Lili"/>
         <br/>
   输出sesion作用域中存入的信息:
         <s:property value = "#session.Jenny"/>
         <br/>
    输出application作用域中存入的信息:
         <s:property value = "#application.Nike"/>
          <s:debug></s:debug>
         <hr/>
         <h3>使用ongl标签输出存入不同作用域中的对象值:</h3>
           输出request作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <br/>
          输出sesion作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <br/>
          输出application作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <s:debug></s:debug>
         <hr/>
         <h3>使用struts标签构建Map</h3>
         <s:iterator var="map" value="#{1:'lihuihui',2:'李晖晖'}">
               <s:property value="key"/>
             <s:property value="value"/>
               <br/> 
            </s:iterator>
            <hr/>
           <s:iterator var="map" value="#{1:'lihuihui',2:'李晖晖'}">
           
               <s:property value="#map.key"/>
             <s:property value="#map.value"/>
              <br/>
            </s:iterator>
           
            <hr/>
              <h3>使用struts标签构建List</h3>
              方式一:<br/>
               <s:iterator var="list" value="{'Java','.NET','PHP'}">
               <s:property value="list"/>
              <br/>
            </s:iterator>
          方式二:<br/>
               <s:iterator var="list" value="{'Java','.NET','PHP','3G'}">
               <s:property />
              <br/>
            </s:iterator>
            <hr/>
          <h3>使用struts标签构建单选按钮</h3>
          方式一:<br/>
            <s:radio list="#{'m':'男','w': '女'}" listKey="key" listValue="value"></s:radio><br/>
             键值互换:
              方式二:<br/>
             <s:radio list="#{'m':'男','w': '女'}" listKey="value" listValue="key"></s:radio>
             <br/>
             方式三:<br/>
            
             <s:radio list="#{'1':'男','0': '女'}" value ="'0'"></s:radio>
            <br/>
             方式四:<br/>
            
             <s:radio list="{'男', '女'}"  value ="'男'"></s:radio>
            <br/>
                <hr/>
          <h3>使用struts标签构建复选框</h3>
            方式一:
          <s:checkbox name="fav" label="看书"/>
           <s:checkbox name="fav" label="写字"/> 
           <s:checkbox name="fav" label="画画"/>
            <s:checkbox name="fav" label="打球"/>
            <br/>
             方式二:
             <s:checkboxlist name = "fav" list="{'看书','写字','画画','打球'}"  value ="'写字','画画'"></s:checkboxlist>
           <br/>
            方式三:
            <s:checkboxlist  name ="fav" list="#{1:'看书',2:'写字',3:'打球'}" value="{1,2}"></s:checkboxlist>
            <br/>
            <hr/>
          <h3>使用struts标签构建下拉列表框</h3>
          方式一:<br/>
          <s:select label="月份" list="#{1:'Jan',2:'Feb',3:'Mar',4:'Apr'}" headerValue="选择月份" headerKey="-1"  required="true"></s:select>
          <br/>
           方式二:<br/>
           <s:select label="月份" list="#{1:'Jan',2:'Feb',3:'Mar',4:'Apr'}" headerValue="选择月份" headerKey="-1"  value="'4'" required="false"></s:select>
             <br/>
           方式三:<br/>
           <s:select label="专业" list="{'Java','.NET','3G','PHP'}" headerValue="选择专业" headerKey="-1"  value="'PHP'" required="false"></s:select>
            方式四:<br/>
           <s:select label="专业" list="{'Java','.NET','3G','PHP'}"   value="'PHP'" ></s:select>
             <hr/>
             <h3>使用struts标签构建if/else/in/not in</h3>      
              <s:if test="'Java' not in {'3G','Java'}">
                  Java is not in list!
              </s:if>
              <s:else>   Java is in list!</s:else>
              <hr/>
            <h3>使用struts标签中的set对属性进行存值</h3>
            <s:set var="user" value="你好用户!<br/>" scope="request"></s:set>
              <s:property value="#user" escape="false"/>
               <hr/>
            <h3>使用struts标签中的push对属性进行存值</h3>
              <s:push value="'lihuihui'">
              <s:property/>
              </s:push>
                 <hr/>
            <h3>使用struts标签中的bean对实体进行赋值并进行存取值</h3>
              <s:bean name="www.csdn.net.domain.Admin"  var = "myAdmin">
               <s:param name="userName">李晖晖</s:param>
                <s:param name="userPassword">12345</s:param>
                输出姓名:
                  <s:property value="userName"/>
               
              </s:bean>
              <br/>
              输出1:<s:property value="#myAdmin.userName"/>
             <br/>
              输出2:
              <s:set var="admin" value = "#myAdmin"></s:set>
              <s:property value="#admin.userName"/>
              <hr/>
         <h3>使用struts标签中的迭代实现表格的变色输出!</h3>
         <table border = "1px">
            <s:iterator var = "tb" value ="{'Java','.NET','PHP','3G'}"  status="st">
              <tr class = "<s:property value = '#st.even?"even":"odd"'/>">
                <td>
                  <s:property value ="tb"/>
                </td>
              </tr>
            </s:iterator>
         </table>
              
  </body>
</html>


效果如图:








Struts标签与OGNL表达式语言实例演练


项目结构如图:


主要类文件如下:

     AdminAction.java

public class AdminAction extends ActionSupport{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Admin admin;
	
	
	public Admin getAdmin() {
		return admin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}

	public String Login(){
//        使用request存值
		ActionContext actionContext = ActionContext.getContext();
		actionContext.put("Lili", "你好!");
//		 使用session存值
		  actionContext.getSession().put("Jenny", "你好Jenny");
//		 使用application存值
		  actionContext.getApplication().put("Nike", "谢谢Nike");
//		 存入对象
//        使用request存值
		 actionContext.put("admin", admin);
//		 使用session存值
		  actionContext.getSession().put("admin", admin);
//		 使用application存值
		  actionContext.getApplication().put("admin", admin);
		  
		return "adminaction_login";
	}

	public String save(){
         System.out.println("保存成功!!!!!!");	
		
		return "adminaction_save";
	}
	public String delete(){
		System.out.println("删除成功!!!!!!");	
		
		return "adminaction_delete";
	}
	public String update(){
		System.out.println("修改成功!!!!!!");	
		
		return "adminaction_update";
	}
	public String find(){
		System.out.println("查询成功!!!!!!");	
		
		return "adminaction_find";
	}
	

}


Admin.java

public class Admin {
  private String userName;
  private String userPassword;
public String getUserName() {
	return userName;
}
public void setUserName(String userName) {
	this.userName = userName;
}
public String getUserPassword() {
	return userPassword;
}
public void setUserPassword(String userPassword) {
	this.userPassword = userPassword;
}
  
  
}
 
struts.xml
	<struts>
	    <package name="struts" namespace="/csdn" extends="struts-default" >
	        <!-- 
	         使用通配符进行测试!
	         -->
	         <action name="*_*" class="www.csdn.net.action.{1}" method="{2}">     
	         <result name="adminaction_loginError" type="dispatcher">/manager/ErrorNormal.jsp </result>
	         <result name="adminaction_login" type="dispatcher">/manager/Login.jsp </result>
	         <result name="adminaction_save" type="dispatcher">/manager/Save.jsp </result>
	         <result name="adminaction_delete" type="dispatcher">/manager/Delete.jsp </result>
	         <result name="adminaction_update" type="dispatcher">/manager/Update.jsp </result>
	         <result name="adminaction_find" type="dispatcher">/manager/Find.jsp </result>
	       </action>
	    </package>
	</struts>




index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
  <body style="text-align: center">    
  <h2>这是第一个使用structs2标签开发的应用测试实例!</h2>
  
    <s:form action="AdminAction_Login" namespace="/csdn" method="post">
      <s:textfield name="admin.userName" label="用户名:"></s:textfield>
      <s:password name="admin.userPassword" label="密码:"></s:password>
      <s:submit  value="登陆"></s:submit> 
      <s:reset value="重置"></s:reset>
     
    </s:form>
  </body>
</html>

主要实例演示:

    Login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'Login.jsp' starting page</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">
   <style type="text/css">
   .even{
      background-color:red;
    }
.odd{
      background-color:blue;
    }
   </style>

    
  </head>
  
  <body style="text-align: center">
  <<<<<---------------------------------------------------------------->>>>>
  <h2>这是第一个使用structs2标签和设置session属性对象开发的应用测试实例!</h2>
  <h3>${admin.userName}用户登陆成功!!!</h3><br/>
  <hr/>
  <h3>使用ongl标签输出存入不同作用域中的值:</h3>
  输出request作用域中存入的信息:
         <s:property value = "#request.Lili"/>
         <br/>
   输出sesion作用域中存入的信息:
         <s:property value = "#session.Jenny"/>
         <br/>
    输出application作用域中存入的信息:
         <s:property value = "#application.Nike"/>
          <s:debug></s:debug>
         <hr/>
         <h3>使用ongl标签输出存入不同作用域中的对象值:</h3>
           输出request作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <br/>
          输出sesion作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <br/>
          输出application作用域中存入的信息:
         <s:property value = "#admin.userName"/>
         <s:debug></s:debug>
         <hr/>
         <h3>使用struts标签构建Map</h3>
         <s:iterator var="map" value="#{1:'lihuihui',2:'李晖晖'}">
               <s:property value="key"/>
             <s:property value="value"/>
               <br/> 
            </s:iterator>
            <hr/>
           <s:iterator var="map" value="#{1:'lihuihui',2:'李晖晖'}">
           
               <s:property value="#map.key"/>
             <s:property value="#map.value"/>
              <br/>
            </s:iterator>
           
            <hr/>
              <h3>使用struts标签构建List</h3>
              方式一:<br/>
               <s:iterator var="list" value="{'Java','.NET','PHP'}">
               <s:property value="list"/>
              <br/>
            </s:iterator>
          方式二:<br/>
               <s:iterator var="list" value="{'Java','.NET','PHP','3G'}">
               <s:property />
              <br/>
            </s:iterator>
            <hr/>
          <h3>使用struts标签构建单选按钮</h3>
          方式一:<br/>
            <s:radio list="#{'m':'男','w': '女'}" listKey="key" listValue="value"></s:radio><br/>
             键值互换:
              方式二:<br/>
             <s:radio list="#{'m':'男','w': '女'}" listKey="value" listValue="key"></s:radio>
             <br/>
             方式三:<br/>
            
             <s:radio list="#{'1':'男','0': '女'}" value ="'0'"></s:radio>
            <br/>
             方式四:<br/>
            
             <s:radio list="{'男', '女'}"  value ="'男'"></s:radio>
            <br/>
                <hr/>
          <h3>使用struts标签构建复选框</h3>
            方式一:
          <s:checkbox name="fav" label="看书"/>
           <s:checkbox name="fav" label="写字"/> 
           <s:checkbox name="fav" label="画画"/>
            <s:checkbox name="fav" label="打球"/>
            <br/>
             方式二:
             <s:checkboxlist name = "fav" list="{'看书','写字','画画','打球'}"  value ="'写字','画画'"></s:checkboxlist>
           <br/>
            方式三:
            <s:checkboxlist  name ="fav" list="#{1:'看书',2:'写字',3:'打球'}" value="{1,2}"></s:checkboxlist>
            <br/>
            <hr/>
          <h3>使用struts标签构建下拉列表框</h3>
          方式一:<br/>
          <s:select label="月份" list="#{1:'Jan',2:'Feb',3:'Mar',4:'Apr'}" headerValue="选择月份" headerKey="-1"  required="true"></s:select>
          <br/>
           方式二:<br/>
           <s:select label="月份" list="#{1:'Jan',2:'Feb',3:'Mar',4:'Apr'}" headerValue="选择月份" headerKey="-1"  value="'4'" required="false"></s:select>
             <br/>
           方式三:<br/>
           <s:select label="专业" list="{'Java','.NET','3G','PHP'}" headerValue="选择专业" headerKey="-1"  value="'PHP'" required="false"></s:select>
            方式四:<br/>
           <s:select label="专业" list="{'Java','.NET','3G','PHP'}"   value="'PHP'" ></s:select>
             <hr/>
             <h3>使用struts标签构建if/else/in/not in</h3>      
              <s:if test="'Java' not in {'3G','Java'}">
                  Java is not in list!
              </s:if>
              <s:else>   Java is in list!</s:else>
              <hr/>
            <h3>使用struts标签中的set对属性进行存值</h3>
            <s:set var="user" value="你好用户!<br/>" scope="request"></s:set>
              <s:property value="#user" escape="false"/>
               <hr/>
            <h3>使用struts标签中的push对属性进行存值</h3>
              <s:push value="'lihuihui'">
              <s:property/>
              </s:push>
                 <hr/>
            <h3>使用struts标签中的bean对实体进行赋值并进行存取值</h3>
              <s:bean name="www.csdn.net.domain.Admin"  var = "myAdmin">
               <s:param name="userName">李晖晖</s:param>
                <s:param name="userPassword">12345</s:param>
                输出姓名:
                  <s:property value="userName"/>
               
              </s:bean>
              <br/>
              输出1:<s:property value="#myAdmin.userName"/>
             <br/>
              输出2:
              <s:set var="admin" value = "#myAdmin"></s:set>
              <s:property value="#admin.userName"/>
              <hr/>
         <h3>使用struts标签中的迭代实现表格的变色输出!</h3>
         <table border = "1px">
            <s:iterator var = "tb" value ="{'Java','.NET','PHP','3G'}"  status="st">
              <tr class = "<s:property value = '#st.even?"even":"odd"'/>">
                <td>
                  <s:property value ="tb"/>
                </td>
              </tr>
            </s:iterator>
         </table>
              
  </body>
</html>


效果如图:






struts2.X心得12--OGNL表达式语言1

1. OGNL表达式语言介绍

OGNL是ObjectGraphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。相对EL表达式,它提供了平时我们需要的一些功能,如:

l    支持对象方法调用,如xxx.sayHello();

l     支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 |  值名],例如:@java.lang.String@format('foo%s', 'bar')或@cn.csdn.Constant@APP_NAME;

l    操作集合对象

l    Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图

2.Struts 2中的OGNL Context实现者为ActionContext,它结构示意图如下:


当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。 访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session

另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。

在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象

    |--request  

    |--application  

context------|--OgnlValueStack root变量[action, OgnlUtil, ... ]  

    |--session  

    |--attr  

    |--parameters

在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。

l    大家注意:Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/>

3.OGNL中的域对象

由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:

${foo}//获得值栈中某个对象的foo属性

如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。

l    application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。

l    session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")

l    request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。

l    parameters对象用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")

l    attr对象用于按page->request->session->application顺序访问其属性。

4. 为何使用EL表达式能够访问valueStack中对象的属性

原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:

 public class StrutsRequestWrapper extends HttpServletRequestWrapper {

       publicStrutsRequestWrapper(HttpServletRequest req) {

           super(req);

       }

       public Object getAttribute(String s) {

        ......

        ActionContext ctx =ActionContext.getContext();

        Object attribute = super.getAttribute(s);//先从request范围获取属性值

        if (ctx != null) {

            if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值

               ......

               ValueStack stack =ctx.getValueStack();

               attribute = stack.findValue(s);

               ......

            }

        }

        return attribute;

    }

 }

5.OGNL的用法总结

   在此先说一部分,后续博客会陆续介绍其他用法总结

(1)、用法1(#号用法)

说明:

1、       访问OGNL上下文和action上下文,#相当于ActionContext.getContext();

2、       如果访问的是map中的值而不是对象栈中的值,由于map中的数据不是根对象,所以在访问时需要添加#前缀。

名称

作用

例子

parameters

包含当前HTTP请求的Map

#parameters.id[0]=request.getParameter(“id”)

request

包含当前HttpServletRequest属性的Map

#request.username=request.getAttribute(“username”);

session

包含当前HttpSession属性的Map

#session.username=session.getAttribute(“username”);

application

包含当前ServletContext属性的Map

#application.username=application.getAttribute(“username”);

attr

用于按照request>session>application顺序访问其属性

#attr.username相当于按照顺序在以上三个范围内读取username的属性,直到找到为止。

注:也可以写为#request[‘username’] #sesssion[‘username’]  #application[‘username’]

   主要步骤:

      在action中

              // 把字符串"request_msg"放入到request域中

              ServletActionContext.getRequest().setAttribute("request_username",

                            "request_username");

              // 把字符串"session_msg"放入到session域中

              ServletActionContext.getRequest().getSession().setAttribute(

                            "session_username", "session_username");

              // 把字符串"application_msg"放入到application域中

              ServletActionContext.getServletContext().setAttribute(

                            "application_username", "application_username");

              return "ognl_scope";

       }

 
  

 

 

 

 

 

 

 

      在页面中:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib uri="/struts-tags" prefix="s"%>  //导入struts2的标签

ognl表达式关于scope(request,session,application)的输出<br>

request:<s:property value="#request.request_username"/><br>

session:<s:property value="#session.session_username"/><br>

application:<s:property value="#application.application_username"/><br>

public String testScope() {

 
  

 

 

 

(2)、用法2

OGNL会设定一个对象(root对象),在struts2中根对象就是CompoundRoot,或者为OgnlValueStack中的root,通常被叫做ValueStack(值栈或者对象栈),如果要访问根对象的属性,则可以省略去#,直接访问对象的属性即可。

   在action中

public String testObjectValue(){

              //得到ognl的上下文

              ValueStack valueStack = ActionContext.getContext().getValueStack();

              valueStack.set("msg", "object_msg");

              return "ognl_objectstack";

       }

 
 

 

 

 


   在页面中:

对象栈的内容:<s:property value="msg"/>

//把对象栈中key值为msg的value的值输出

 

Struts2常用标签总结

一 介绍
1.Struts2的作用    
Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,多变的需求。
    Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何表现层技术,也就是说strtus2提供了大部分标签,可以在各种表现技术中使用。包括最常用的jsp页面,也可以说Velocity和FreeMarker等模板技术中的使用
2.Struts2分类
(1)UI标签:(User  Interface, 用户界面)标签,主要用于生成HTML元素标签,UI标签又可分为表单标签非表单标签
(2)非UI标签,主要用于数据访问,逻辑控制等的标签。非UI标签可分为流程控制标签(包括用于实现分支、循环等流程控制的标签)和数据访问标签(主要包括用户输出ValueStack中的值,完成国际化等功能的)
(3)ajax标签
3.Struts2标签使用前的准备:
(1)在要使用标签的jsp页面引入标签库:    
<%@ taglib uri="/struts-tags" prefix="s"%>
(2)在web.xml中声明要使用的标签    这样是struts2 2.3.1.2版本的引入方式
<filter>
        <filter-name>struts2</filter-name>
                         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
4.标签的使用
(1)property标签
    用于输出指定的值:
    <s:property value="%{@cn.csdn.hr.domain.User@Name}"/><br/>
        <s:property value="@cn.csdn.hr.domain.User@Name"/><Br/><!-- 以上两种方法都可以 -->
        <s:property value="%{@cn.csdn.hr.domain.User@study()}"/>
    以上可以访问某一个包的类的属性的集中方式,study()是访问方法的方法,并输出。


    以下用java代码代替的,访问某一个范围内的属性
    <%
    //采用pageContext对象往page范围内存入值来 验证#attr搜索顺序是从page开始的 ,搜索的顺序为:page,reques,session,application。
set存值的时候存到的是request中,在jsp页面中访问的时候不用加任何的标识符,即可直接访问,如果不同的作用域不一样了,
pageContext.setAttribute("name", "laoowang", PageContext.PAGE_SCOPE);
%>
<s:property value="#attr.name" /> 


假设在action中设置了不同作用域的类
不同的作用域的标签的访问:
      
  <h3>获取的是requet中的对象值</h3>
  第一种方式:<s:property value="#request.user1.realName"/>
  <br/>
  第二种方式:<s:property value="#request.user1['realName']"/>
   <br/>
  第三种方式:<s:property value="#user1.realName"/>
   <br/>
    第四种方式:<s:property value="#user1['realName']"/>
      <br/>
       第五种方式:${requestScope.user1.realName }  || ${requestScope.user1['realName'] }
       
   第六种:<s:property value="#attr.user1.realName"/>
  attr对象按page==>  request sessionapplictio找的
  
  
  <h3>获取session中的值</h3>
    第一种方式:<s:property value="#session.user1.realName"/>
  <br/>
  第二种方式:<s:property value="#session.user1['realName']"/>
  
  
    第五种方式:${sessionScope.user1.realName }  || ${sessionScope.user1['realName'] }
  
  <h3>获取application中的对象的值</h3>
    第一种方式:<s:property value="#application.user1.realName"/>
  <br/>
  第二种方式:<s:property value="#application.user1['realName']"/>
  
  
    第五种方式:${applicationScope.user1.realName }  || ${applicationScope.user1['realName'] }
    
(2)iterator标签的使用
    第一种:list集合
        <!-- 设置set集合  value-->
        <!-- status 可选属性,该属性指定迭代时的IteratorStatus实例 -->
        <!-- value="#attr.list"   list存放到了request中  可以value="#request.list"
                    statu.odd返回当前被迭代元素的索引是否是奇数
                -->
    <s:set name="list" value="{'a','b','c','d'}"></s:set>
        <s:iterator var="ent" value="#request.list" status="statu">
            <s:if test="%{#statu.odd}">
                <font color="red"><s:property value="#ent" />
                </font>
            </s:if>
            <s:else>
        <s:property value="#ent" />
        </s:else>
</s:iterator>
    
第二种:map集合中的使用
    <h3>Map集合</h3>
                <!-- map集合的特点: 
                  语法格式:# {key:value,key1:value1,key2:value2,.....}   
 以上的语法中就直接生成了一个Map类型的集合,该Map对象中的每个key-value对象之间用英文的冒号隔开   
   ,多个元素之间用逗号分隔。   
                -->
            </div>

            <s:set var="map" value="#{'1':'laowang','2':'老王','3':'猩猩'}"></s:set>
            遍历Map:
            <br />
            <s:iterator value="#map">
                <s:property value="key" />:::<s:property value="value" />
                <Br />
            </s:iterator>\

第三种:集合的变量
<h3>遍历集合:::</h3>
            <div>
                <!-- 遍历出价格大于3000的 -->
                <s:iterator var="user" value="#session['users']">
                    <s:if test="%{#user['price']>3000}">
                        <s:property value="#user['price']"/>
                    </s:if>
                </s:iterator>
                
                
                <hr color="blue"/><!-- $是取出价格 大于3000的最后一个值 -->
                <s:iterator var="u" value="#session.users.{$(#this['price']>3000)}">
                    <s:property value="price"/>
                </s:iterator>
            </div>
注:users是User的对象,price是User中的一个属性

简述一下iterator的介绍:
iterator标签用于对集合进行迭代,这里的集合包含List、Set和数组。
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iterator value="#list" status="st">
    <font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>>
    <s:property /></font><br>
</s:iterator> 
value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
id:可选属性,指定集合里元素的id。
status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法:
    int getCount(),返回当前迭代了几个元素。
    int getIndex(),返回当前迭代元素的索引。
    boolean isEven(),返回当前被迭代元素的索引是否是偶数
    boolean isOdd(),返回当前被迭代元素的索引是否是奇数
    boolean isFirst(),返回当前被迭代元素是否是第一个元素。
    boolean isLast(),返回当前被迭代元素是否是最后一个元素。


(3)if else语句的使用
    <s:set name="age" value="21" />
<s:if test="#age==23">
    23
</s:if>
<s:elseif test="#age==21">
    21
</s:elseif>
<s:else>
    都不等
</s:else> 

(4)URL标签
    <!-- 声明一个URL地址 -->
        <s:url action="test" namespace="/tag" var="add">
            <s:param name="username">laowangang</s:param>
            <s:param name="id">12</s:param>
        </s:url>
        <s:a href="%{add}">测试URL</s:a>
        <s:a action="test" namespace="/tag"></s:a>
    以上的两个<s:a>标签的作用是一样的。
(5)data标签
<%
            pageContext.setAttribute("birth",new Date(200,03,10),PageContext.REQUEST_SCOPE);
         %>
        <s:date name="#request.birth" format="yyyy年MM月dd日"/>
        <s:date name="#request.birth" nice="true"/>
    这个标签是按照format的格式去输出的。

(6)表单

            
        <h1>from表单</h1>
        <s:form action="test" namespace="/tag">
            <s:textfield label="用户名" name="uname" tooltip="你的名字" javascriptTooltip="false"></s:textfield>
            <s:textarea  name="rmake" cols="40" rows="20" tooltipDelay="300" tooltip="hi" label="备注" javascriptTooltip="true"></s:textarea>
            <s:password label="密码" name="upass"></s:password>
            <s:file name="file" label="上传文件"></s:file>
            <s:hidden name="id" value="1"></s:hidden>
            
            <!-- 
            <select name="edu">
                <option value="listKey">listValue</option>
             -->
            <s:select list="#{'1':'博士','2':'硕士'}" name="edu" label="学历" listKey="key" listValue="value"></s:select>
            
            <s:select list="{'java','.net'}" value="java"></s:select><!-- value是选中的 -->
            
            <!-- 必须有name -->
            <s:checkbox label="爱好 " fieldValue="true" name="checkboxFiled1"></s:checkbox>
            
            <!-- 多个checkbox -->
            <s:checkboxlist list="{'java','css','html','struts2'}" label="喜欢的编程语言" name="box" value="{'css','struts2'}"></s:checkboxlist>
        
        
            <!-- map集合前要加# -->
            <s:checkboxlist list="#{1:'java',2:'css',3:'html',4:'struts2',5:'spring'}" label="喜欢的编程语言" name="boxs" value="{1,2}"></s:checkboxlist>
            
            
            <!-- listKey 
                listValue
                
                <input type="text" name="boxs" value="listKey">显示值listValue
             -->
                    
            <!-- radio -->        
            <%
                //从服务器传过来值 
                pageContext.setAttribute("sex","男",PageContext.REQUEST_SCOPE);
                pageContext.setAttribute("sex1","男",PageContext.REQUEST_SCOPE);
             %>
            <s:radio list="{'男','女'}" name="sex" value="#request.sex"></s:radio>    
            
            
            <s:radio list="#{1:'男',2:'女'}" name="sex1" listKey="key" listValue="value" value="#request.sex1"></s:radio>            
        
            <!-- 防止表单提交的方式 -->
            <s:token></s:token>
                            
            <s:submit value="提交"></s:submit>
        </s:form>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值