目录
值栈/OGNL:
OGNL(Object-Graph Navigation Language,对象图导航语言)是一种强大的表达式语言,用于引用和操作值栈上的数据,还可用于数据传输和类型转换。
OGNL非常类似于JSP表达式语言。OGNL基于上下文中存有根对象或默认对象的理念,使用标记符号(即#号)来引用默认或根对象的属性。
如前面所述,OGNL是基于上下文的,而Struts构建了一个ActionContext映射以供OGNL使用。 ActionContext映射包含以下内容:
应用程序 - 应用程序作用域变量
会话 - 会话作用域变量
根/值栈 - 所有的action变量都存储在这里
请求 - 请求作用域变量
参数 - 请求参数
属性 - 存储在页面,请求,会话和应用程序作用域中的属性
package com.leo.struts2.ognl;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.opensymphony.xwork2.ActionSupport;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
/**
* 取出Map属性的值
* @author leoi555
*
*/
public class OgnlDemo extends ActionSupport {
/**
* 获得根属性值
* @throws OgnlException
*/
@Test
public void test() throws OgnlException {
User root=new User("tom",23);
Map<String , Object> map=new HashMap<>();
map.put("user1", new User("jack",12));
map.put("user2", new User("we", 20));
OgnlContext oContext=new OgnlContext();
//将root作为root部分
oContext.setRoot(root);
oContext.setValues(map);
//书写OGNL
//Ognl.getValue("", oContext, oContext.getRoot());
//取出User 中对象的属性
String name=(String)Ognl.getValue("username",oContext,oContext.getRoot());
System.out.println(name);
}
/**
* 获取根对应得栈值
* @throws OgnlException
*/
@Test
public void test1() throws OgnlException {
User user=new User("tom",23);
Map<String , Object> map=new HashMap<>();
map.put("user1", new User("jack",12));
map.put("user2", new User("we", 20));
OgnlContext oContext=new OgnlContext();
oContext.setRoot(user);
oContext.setValues(map);
//取出context属性就是把map对象添加到里面
//获取context对象的属性值
String name2=(String)Ognl.getValue("#user1.username",oContext,oContext.getRoot());
System.out.println(name2);
int name23=(int)Ognl.getValue("#user1.age",oContext,oContext.getRoot());
System.out.println(name23);
}
/**
* =赋值
*/
@Test
public void test2() throws OgnlException {
User user=new User("tom",23);
Map<String , Object> map=new HashMap<>();
map.put("user1", new User("jack",12));
map.put("user2", new User("we", 20));
OgnlContext oContext=new OgnlContext();
oContext.setRoot(user);
oContext.setValues(map);
//赋值然后在取值
String name2=(String)Ognl.getValue("#user1.username='张三'",oContext,oContext.getRoot());
System.out.println(name2);
int name23=(int)Ognl.getValue("#user1.age=122",oContext,oContext.getRoot());
System.out.println(name23);
}
/**
* 调用方法:通过方法设置属性
*
*
*/
@Test
public void test3() throws OgnlException {
User user=new User("tom",23);
Map<String , Object> map=new HashMap<>();
map.put("user1", new User("jack",12));
map.put("user2", new User("we", 20));
OgnlContext oContext=new OgnlContext();
oContext.setRoot(user);
oContext.setValues(map);
String name=(String) Ognl.getValue("getUsername()", oContext,oContext.getRoot());
System.out.println(name);
String name1=(String )Ognl.getValue("setUsername('nic'),getUsername()", oContext,oContext.getRoot());
System.out.println(name1);
//调用静态属性
Double pi=(Double)Ognl.getValue("@@PI", oContext,oContext.getRoot());
System.out.println(pi);
}
/**
* 取出list map集合
*/
@Test
public void test4() throws Exception{
//准备ONGLContext
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map<String,User> context = new HashMap<String,User>();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
oc.setRoot(rootUser);
oc.setValues(context);
//书写OGNL
//创建list对象
Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());
System.out.println(size);
System.out.println(name);
System.out.println(name2);
//创建Map对象
Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
String name3 = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());
System.out.println(size2);
System.out.println(name3);
System.out.println(age);
}
}
API:
获取API:
ActionContext获取一切得request,response,servletContext对象,application attr域,session域,等Map类型
这些方式只是实现ActionSupport类即可获取以下对象:
方式一:通过ActionContext
//actionContext推荐使用代替map
ActionContext context=ActionContext.getContext();
Map<String, Object> sessionScope=ActionContext.getContext().getSession();
//不推荐使用request域包装
Map<String, Object> requestScope=(Map<String, Object>) context.get("request");
Map<String , Object> responseScope=(Map<String, Object>) context.get("response");
//用于获取页面域
Map<String , Object> applicationScope=context.getApplication();
//这个是
Map<String, Object> servletContext=(Map<String, Object>) context.get("ServletContext");
requestScope.put("name","123");
applicationScope.put("name", "124");
sessionScope.put("name", "1333");
调用时直接用${requestScope.name};
方式二:通过ServlertActionContext来获取ServlertAPI;
HttpServletRequest request=ServletActionContext.getRequest();
Map<String,String[]> map=request.getParameterMap();
for(String key:map.keySet()){
String[] value=map.get(key);
}
//向request域中添加值:
request.setAttribute("name","value");
//向session域存值:
request.getSession().setAttribute("sessionname","value");
//向Application域中存入:
ServletActionContext.getServletContext().setAtrribute("attrname","attvalue");
标签:
<s:if test="%{false}">
<div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
<div>Will Be Executed</div>
</s:elseif>
<s:else>
<div>Will Not Be Executed</div>
</s:else>
//
<s:text name="Please fill in the form below:" />
<s:form action="hello" method="post" enctype="multipart/form-data">
<!-- 表单隐藏项 -->
<s:hidden name="secret" value="abracadabra"/>
<s:textfield key="email.from" name="from" />
<s:password key="email.password" name="password" />
<s:textfield key="email.to" name="to" />
<s:textfield key="email.subject" name="subject" />
<s:textarea key="email.body" name="email.body" />
<s:label for="attachment" value="Attachment"/>
<s:file name="attachment" accept="text/html,text/plain" />
<s:token />
<!-- 单选框 -->
<s:radio label="Gender" name="gender" list="{'male','female'}" />
<!-- 复选框 -->
<s:checkboxlist label="Hobbies" name="hobbies"
list="{'sports','tv','shopping'}" />
<!-- 下拉框标签 -->
<s:select name="username" label="Username"
list="{'Mike','John','Smith'}" />
<s:select label="Company Office" name="mySelection"
value="%{'America'}"
list="%{#{'America':'America'}}">
<s:optgroup label="Asia"
list="%{#{'India':'India','China':'China'}}" />
<s:optgroup label="Europe"
list="%{#{'UK':'UK','Sweden':'Sweden','Italy':'Italy'}}" />
</s:select>
<s:combobox label="My Sign" name="mySign"
list="#{'aries':'aries','capricorn':'capricorn'}"
headerKey="-1"
headerValue="--- Please Select ---" emptyOption="true"
value="capricorn" />
<s:doubleselect label="Occupation" name="occupation"
list="{'Technical','Other'}" doubleName="occupations2"
doubleList="top == 'Technical' ?
{'I.T', 'Hardware'} : {'Accounting', 'H.R'}" />
<!--Ajax标签 struts2-dojo-plugin-2.2.3.jar -->
<s:form>
<sx:autocompleter label="Favourite Colour"
list="{'red','green','blue'}" />
<br />
<sx:datetimepicker name="deliverydate" label="Delivery Date"
displayFormat="dd/MM/yyyy" />
<br />
<s:url id="url" value="/hello.action" />
<sx:div href="%{#url}" delay="2000">
Initial Content
</sx:div>
<br/>
<sx:tabbedpanel id="tabContainer">
<sx:div label="Tab 1">Tab 1</sx:div>
<sx:div label="Tab 2">Tab 2</sx:div>
</sx:tabbedpanel>
</s:form>
说明:
s:head生成Struts2 应用程序所需的javascript和stylesheet元素。
接下来,s:div和s:text元素。s:div用于呈现HTML Div元素。
这对于不喜欢将HTML和Struts标签混合在一起的人很有用,他们可选择使用s:div来渲染div。
s:text用于在屏幕上呈现文本。
接下来是相类似的s:form标签。s:form标签具有确定在何处提交表单的action属性。
因为在表单中有一个文件上传元素,我们必须将enctype设置为multipart。否则,就留空。
在表单标签的末尾,有s:submit标签,这用于提交表单。提交表单时,所有表单值都将提交到s:form标签中指定的action。
在s:form标签中,我们有一个称为secret的隐藏属性,此元素对最终用户不可见,并用于将状态从一个视图传递到另一个视图。
s:label,s:textfield,s:password和s:textarea标签。这些分别用于渲染标签,输入字段,密码和文本区域。
“key”属性用于从属性文件中提取这些控件的标签。我们已经在Struts2本地化/国际化(i18n)一章中讨论了这个特性。
然后是s:file标签,它呈现输入文件上传的组件,此组件允许用户上传文件。
在这个例子中,我们使用了s:file标签的“accept”参数来指定允许上传哪些文件类型。
最后,s:token标签。token标签生成唯一的token,用于查明表单是否已被两次提交。呈现表单时,会将一个隐藏变量放置为token(令牌)值。
例如令牌是“ABC”,提交此表单时,Struts Fitler将根据存储在会话中的令牌进行检查。如果匹配,则从会话中删除令牌。现在,如果表单意外被重新提交(通过刷新或通过点击浏览器后退按钮),表单将重新提交,用“ABC”作为令牌。在这种情况下,过滤器将对照存储在会话中的令牌再次进行检查。但是因为令牌“ABC”已经从会话中删除,它将不匹配,Struts过滤器将拒绝请求。