您的位置:首页 > 编程语言 > Java开发

第30天(就业班) 拦截器、国际化、标签

2017-02-22 13:33 155 查看
1.
struts2拦截器

基本概述:

Intercetor, 即为拦截器。

1) 在Struts2中,把每一个功能都用一个个的拦截器实现;用户想用struts的哪个功能的时候,可以自由组装使用。

2)Struts2中,为了方法用户对拦截器的引用,提供了拦截器栈的定义,里面可以包含多个拦截器。   文件夹(文件, 文件2)  拦截器栈(拦截器,拦截器2)

3)Struts2中,如果用户没有指定执行哪些拦截器,struts2有一个默认执行的栈,defaultStack;

  一旦如果用户有指定执行哪些拦截器,默认的拦截器栈就不会被执行

拦截器的设计,就是基于组件设计的应用!

 拦截器配置举例

struts-default.xml文件中,定义了struts提供的所有拦截器!

//1. 定义拦截器以及拦截器栈

<interceptors>

    1.1 拦截器定义

    <interceptor name="" class="" /> 

    1.2 拦截器栈的定义

    <interceptor-stack name="defaultStack">
引用了上面拦截器(1.1)

    </interceptor-stack>

</interceptors>

2. 默认执行的拦截器(栈)

<default-interceptor-ref name="defaultStack"/>

 API

|-- Interceptor  拦截器接口

   |-- AbstractInterceptor  拦截器默认实现的抽象类; 一般用户只需要继承此类即可继续拦截器开发

|-- ActionInvocation 拦截器的执行状态,调用下一个拦截器或Action

拦截器与过滤器的区别:

 案例:  实现用户的登陆下载

      1、jsp 实现下载超链接

       2、action 中提供下载方法

       3、如何在执行下载方法之前判断用户是否登陆?

      4、回顾Struts2的执行流程图?  

            请求过滤器(web.xml)拦截器(struts2)Action

 Struts2拦截器概述

      Struts2 拦截器在访问某个 Action 方法之前或之后实施拦截, Struts2 拦截器是可插拔的, 拦截器是 AOP 的一种实现。

拦截器栈(Interceptor Stack): 将拦截器按一定的顺序联结成一条链. 在访问被拦截的方法时, Struts2拦截器链中的拦截器就会按其之前定义的顺序被依次调用。

拦截器工作原理

当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。



启动:

    创建所有拦截器、执行init()

访问:

    先创建Action,

    再执行拦截器,

    最后:拦截器放行,执行execute();

Struts2拦截器(自定义)

Interceptor接口

    com.opensymphony.xwork2.interceptor.Interceptor

      阅读该接口API,所有的自定义拦截器都需要实现该接口,且以单例运行。

      init: 创建后初始化时被调用, 它在拦截器的生命周期内只被调用一次。

      interecept: 每拦截一个动作请求, 该方法就会被调用一次。

      destroy: 拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次.

Struts2自定义拦截器实现

      1、定义一个类实现Interceptor接口

      2、实现生命周期方法

      3、声明和引用自定义拦截器

自定义拦截器的声明和使用



注意自定义拦截器一定要在默认拦截器的下面

发布应用到tomcat,服务器启动的时候就会执行自定义拦截器的生命周期方法,重新发布应

用会先销毁上次的拦截器再重新创建拦截器对象。对所有请求的方法拦截。

Interceptor接口的intercept方法分析

      publicString intercept(ActionInvocation invocation) throws Exception {

       returnnull;

    }

      ActionInvocation:代表一个给定Action的执行状态, 拦截器可以从该类的对象里获得与该Action相关联的 Action 对象和 Result 对象. 在完成拦截器自己的任务之后, 拦截器将调用 ActionInvocation 对象的 invoke 方法前进到 Action 处理流程的下一个环节.

实现对ActionInvocation的访问



返回值和Action的返回值作用相同 


案例实现



Login方法







自定义拦截器示例
package com.xp.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class HelloInterceptor implements Interceptor{
private static final long serialVersionUID = 1L;
// 启动时候执行
public HelloInterceptor(){
System.out.println("创建了拦截器对象");
}
// 启动时候执行
@Override
public void init() {
System.out.println("执行了拦截器的初始化方法");
}
// 拦截器业务处理方法 (在访问action时候执行? 在execute之前执行?)
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("2. 执行Action之前");
// 调用下一个拦截器或执行Action (相当于chain.doFilter(..)
// 获取的是: execute方法的返回值
String resultFlag = invocation.invoke();

System.out.println("4. 拦截器,业务处理-结束" + resultFlag);
return resultFlag;
}
@Override
public void destroy() {
System.out.println("销毁....");
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<package name="hello" extends="struts-default">
<!-- 【拦截器配置】 -->
<interceptors>
<!-- 配置用户自定义的拦截器 -->
<interceptor name="helloInterceptor" class="com.xp.interceptor.HelloInterceptor"></interceptor>
<!-- 自定义一个栈: 要引用默认栈、自定义的拦截器 -->
<interceptor-stack name="helloStack">
<!-- 引用默认栈 (一定要放到第一行)-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用自定义拦截器 -->
<interceptor-ref name="helloInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 【执行拦截器】 -->
<default-interceptor-ref name="helloStack"></default-interceptor-ref>
<action name="hello" class="com.xp.interceptor.HelloAction">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
运行结果:
1. Action实例创建了
2. 执行Action之前
3. 执行了请求处理的方法: execute
4. 拦截器,业务处理-结束success
1. 案例

需求:

    登陆后,显示列表!

案例准备:

    Struts jar文件

    DbUtils组件

    数据库连接池/ 驱动包



package com.xp.entity;
public class Admin {
private int id;
private String userName;
private String pwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}

package com.xp.utils;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils {
// 初始化连接池
private static DataSource dataSource;
static {
dataSource = new ComboPooledDataSource();
}

public static DataSource getDataSource() {
return dataSource;
}
/**
* 创建DbUtils常用工具类对象
*/
public static QueryRunner getQuerrRunner() {
return new QueryRunner(dataSource);
}
}
package com.xp.dao;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.xp.entity.Admin;
import com.xp.utils.JdbcUtils;

public class AdminDao {
public Admin login(Admin admin){
String sql = "select * from admin where userName=? and pwd=?";
try {
return JdbcUtils.getQuerrRunner()
.query(
sql,
new BeanHandler<Admin>(Admin.class),
admin.getUserName(),
admin.getPwd()
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

public List<Admin> getAll(){
String sql = "select * from admin ";
try {
return JdbcUtils.getQuerrRunner()
.query(
sql,
new BeanListHandler<Admin>(Admin.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

package com.xp.service;

import java.util.List;

import com.xp.dao.AdminDao;
import com.xp.entity.Admin;

public class AdminService {
private AdminDao adminDao = new AdminDao();

public Admin login(Admin admin){
try {
return adminDao.login(admin);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public List<Admin> getAll(){
try {
return adminDao.getAll();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

package com.xp.interceptor;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;

public class UserCheckInterceptor {
/**
* 拦截器业务处理方法
*/
public String intercept(ActionInvocation invocation) throws Exception {
// 拿到当前执行的方法名:判断,只有当前方法名不是login,就进行验证

// 获取ActionContext对象
ActionContext ac = invocation.getInvocationContext();

// 获取action的代理对象
ActionProxy proxy = invocation.getProxy();
// 获取当前执行的方法名
String methodName = proxy.getMethod();
// 判断
if (!"login".equals(methodName)) {
// 先获取当前登陆的用户
Object obj = ac.getSession().get("userInfo");
if (obj == null) {
// 没有登陆
return "input";
} else {
// 当前用户有登陆
return invocation.invoke();
}
} else {
// 说明当前用户正在登陆
return invocation.invoke();
}
}
}

package com.xp.action;

import java.util.List;

import com.xp.entity.Admin;
import com.xp.service.AdminService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport {
private static final long serialVersionUID = 1L;
// ---------1. 封装请求数据-----------
private Admin admin;
public Admin getAdmin() {
return admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
// ---------2. 调用的Service-----------
private AdminService adminService = new AdminService();

// 登陆
public String login() {
try {
Admin userInfo = adminService.login(admin);
// 判断
if (userInfo == null){
// 登陆失败
return "input";
}
// 登陆成功:数据保存在session中
ActionContext.getContext().getSession().put("userInfo", userInfo);

// 登陆成功
return "loginSuccess";
} catch (Exception e) {
return ERROR;
}
}

// 列表
public String list() {
try {
// 查询全部
List<Admin> list = adminService.getAll();
// 保存到request
ActionContext.getContext().getContextMap().put("listAdmin", list);
return "list";
} catch (Exception e) {
return ERROR;
}
}

public String add() {
return null;
}
}
username=User Name
pwd=Password
submit=On Submit
title=Title

username=\u7528\u6237\u540D
pwd=\u5BC6\u7801
submit=\u63D0\u4EA4
title=\u6807\u9898

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<!-- 通过常量加载资源文件 -->
<constant name="struts.custom.i18n.resources" value="com.xp.config.msg"></constant>

<package name="user" extends="struts-default">
<!-- 【拦截器配置】 -->
<interceptors>
<interceptor name="loginCheck" class="com.xp.interceptor.UserCheckInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="loginCheck"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 【执行拦截器:第一种写法: 当前包下所有的acntion都执行myStack栈】
<default-interceptor-ref name="myStack"></default-interceptor-ref>
-->

<!-- 全局配置 -->
<global-results>
<result name="error">/error.jsp</result>
</global-results>

<action name="user_*" class="com.xp.action.UserAction" method="{1}">
<!--第二种写法: 只是在这一个Action中执行myStack栈
<interceptor-ref name="defaultStackt"></interceptor-ref>
<interceptor-ref name="loginCheck"></interceptor-ref>
-->
<!-- 第三种写法:执行用户栈(与第二种写法一样, 只在当前aciton中执行自定义栈) -->
<interceptor-ref name="myStack"></interceptor-ref>
<!-- 1. 登陆失败 -->
<result name="input">/login.jsp</result>

<!-- 2. 登陆成功 -->
<result name="loginSuccess" type="redirectAction">user_list</result>

<!-- 3. 列表展示 -->
<result name="list">/WEB-INF/list.jsp</result>

</action>
</package>

<!-- 引入hello.xml文件 -->
<include file="com/xp/interceptor/hello.xml"></include>
</struts>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.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">
</head>

<body>
<form method="post" action="${pageContext.request.contextPath }/user_login.action">
用户名:<input type="text" name="admin.userName"><br/>
密码:<input type="text" name="admin.pwd"><br/>
<input type="submit" value="登陆"><br/>
</form>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><s:text name="title"></s:text></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>

<body>
<form method="post" action="${pageContext.request.contextPath }/user_login.action">
用户名:<input type="text" name="admin.userName"><br/>
密码:<input type="text" name="admin.pwd"><br/>
<input type="submit" value="登陆"><br/>
</form>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>list</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<h1>欢迎你,${userInfo.userName }</h1>
<table align="center" border="1">
<tr>
<td>序号</td>
<td>编号</td>
<td>用户名</td>
<td>密码</td>
</tr>
<%--@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" --%>
<!-- 用struts标签迭代数据 -->
<%@taglib uri="/struts-tags" prefix="s" %>
<s:iterator var="admin" value="#request.listAdmin" status="st">
<tr>
<td>
<s:property value="#st.count"/>
</td>
<td>
<s:property value="#admin.id"/>
</td>
<td>
<s:property value="#admin.userName"/>
</td>
<td>
<s:property value="#admin.pwd"/>
</td>
</tr>
</s:iterator>
</table>
</body>
</html>

<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///day30</property>
<property name="user">root</property>
<property name="password">xiongpan</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</default-config>
<named-config name="oracleConfig">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///day30</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</named-config>
</c3p0-config>
2.struts2国际化


什么是本地化和国际化

     
软件的本地化:
一个软件在某个国家或地区使用时,采用该国家或地区的语言,数字,货币,日期等习惯。
     
软件的国际化:
软件开发时,让它能支持多个国家和地区的本地化应用。使
      得应用软件能够适应多个地区的语言和文化风俗习惯。

国际化原理

     
本地化信息
       资源文件    基本名_语言名_国家码.properties   基本名.properties(默认)
       加载资源文件
       显示资源文件信息

资源文件

      中文:resource_zh_CN.properties
      英文:resource_en_US.properties
      默认:resource.properties
      存储在同Action所在的包下。
1.  写资源文件

Msg.properties   默认的语言环境; 找不到配置就找它

Msg_en_US.properties  美国

-2.  加载

<constant name="struts.custom.i18n.resources" value="cn.itcast.config.msg"></constant>

3. 使用: 标签name值直接写配置文件中的key

<s:text name="title"></s:text>

另外一点,
(推荐)加载资源文件通过常量加载
还可以在页面加载, 这样用:
<s:i18n name="cn.itcast.config.msg">
<s:text>  标签必须放到标签体中。

</s:i18n>

 加载资源文件(常量的方法)  struts.xml

      <!-- 

       com.xp.upload.fileupload加载fileupload.properties文件

       com.xp.i18n.resource加载resource.properties系列文件

      -->

     <constant name="struts.custom.i18n.resources"

         value="com.xp.upload.fileupload,com.xp.i18n.resource"></constant>

回顾:Servlet 中国际化:
1. 写资源文件
基础名.properties  【默认的语言环境的配置】  
基础名_语言简称_国家简称.properties
2. 读取资源文件,再使用
程序:ResourceBundle
Jsp:   jstl提供的格式化与国际化标签库。

Struts2中国际化:
1. 写资源文件  (同servlet)
2. 读资源文件
程序:ResourceBundle   (同servlet)
JSP:  
1)jstl表亲啊  (同servlet)
2)struts标签获取资源文件内容

区别:
Struts2加载资源文件更加简单!通过常量加载即可!再在jsp页面直接使用!

 获取资源文件数据

      加载Struts2标签库:<%@ taglib uri="/struts-tags" prefix="s" %>

      使用text标签获取资源文件信息:<s:text name="login.name"></s:text>

      如:资源文件中信息   login.name=User Name\:

 不使用常量的方式加载资源文件

      1、删除常量的设置

       2、登陆页面

         <s:i18n name="cn.itcast.i18n.resource">  加载资源文件,包.资源基本名

             <!--包裹需要获取国际化资源文件的标签-->

         </s:i18n>

3.ognl

 OGNL表达式

       OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

 OGNL优势

      1、支持对象方法调用,如xxx.doSomeSpecial(); 

       2、支持类静态的方法调用和值访问,表达式的格式:

             @[类全名(包括包路径)]@[方法名 |  值名],例如:

             @java.lang.String@format('foo %s', 'bar')

             或@tutorial.MyConstant@APP_NAME; 

       3、支持赋值操作和表达式串联,如price=100, discount=0.8,

             calculatePrice(),这个表达式会返回80; 

       4、访问OGNL上下文(OGNL context)和ActionContext; 

       5、操作集合对象。

 总结

        OGNL 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了  

         java.utils.Map 的接口。

 Struts框架默认就支持Ognl表达式语言。

(struts必须引用的包:ognl.jar)

 作用

页面取值用。

El表达式语言,用于页面取值,jsp页面取值的标准。(默认直接可以使用) 
(应用范围更广。)

Ognl表达式语言, struts标签默认支持的表达式语言。
 必须配置struts标签用,不能离开struts标签直接用。

 Ognl的API类和方法

 OgnlContext类【本质是一个Map】
OgnlContext context = new OgnlContext();
context.put("user", user);
context.put("address", address);
context.setRoot(address)
 Ognl类
Object obj1 = Ognl.parseExpression(“country”); 解析ognl表达式
Ognl.getValue(obj1, context, context.getRoot()); 获取ognl的表达式值
Object obj2 = Ognl.parseExpression(“language.toUpperCase()”); 方法调用
Object obj3 = Ognl.parseExpression("@java.lang.Integer@toBinaryString(10)");
Object obj4 = Ognl.parseExpression(“@@min(10,4)”); Math类的方法直接调用
package com.xp.ognl;

import ognl.Ognl;
import ognl.OgnlContext;

import org.junit.Test;

public class OgnlDemo1 {
/**
* 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号
* @throws Exception
*/
@Test
public void testOgnl() throws Exception {
// 创建一个Ognl上下文对象
OgnlContext context = new OgnlContext();
// 放入数据
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往非根元素放入数据, 取值的时候表达式要用"#"】
context.put("user", user);

// 获取数据(map)
// 先构建一个Ognl表达式, 再解析表达式
Object ognl = Ognl.parseExpression("#user.name");
Object value = Ognl.getValue(ognl, context, context.getRoot());

System.out.println(value);
}

/**
* 2. Ognl表达式语言语言取值,取根元素的值,不用带#号
* @throws Exception
*/
@Test
public void testOgn2() throws Exception {
// 创建一个Ognl上下文对象
OgnlContext context = new OgnlContext();
// 放入数据
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往根元素放入数据】
context.setRoot(user);

// 获取数据(map)
// 先构建一个Ognl表达式, 再解析表达式
Object ognl = Ognl.parseExpression("address.province");
Object value = Ognl.getValue(ognl, context, context.getRoot());

System.out.println(value);
}

/**
* 3.Ognl对 静态方法调用的支持
* @throws Exception
*/
@Test
public void testOgn3() throws Exception {
// 创建一个Ognl上下文对象
OgnlContext context = new OgnlContext();

// Ognl表单式语言,调用类的静态方法
//Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
// 由于Math类在开发中比较常用,所以也可以这样写
Object ognl = Ognl.parseExpression("@@floor(10.9)");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
}

Struts2的值栈ValueStack理解
 ValueStack
ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础。
 ValueStack特点
ValueStack贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个
ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前Action 对象和其他相关对象.
Struts2框架把 ValueStack 对象保存在名为 “struts.valueStack” 的request请求属性中。
 ValueStack存储对象
ObjectStack: Struts 把动作和相关对象压入 ObjectStack 中--List
ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 ContextMap 中
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application
 ValueStack获取
ValueStack valuestack1 = (ValueStack) request.getAttribute("struts.valueStack")
ValueStack valuestack2 = ServletActionContext.getContext().getValueStack();
直接输出类引用变量可见值栈类 com.opensymphony.xwork2.ognl.OgnlValueStack

















#号的作用

      #号还有一个作用就是在JSP页面中构建Map集合。

      格式:#{key:value,key:value...}

 举例

      Struts2的radio标签主要任务是在页面中显示单选按钮

      <s:radio list="#{'male':'男','female':'女'}" name="gender"></s:radio><br/>

      运行结果源码:

       <input type="radio" name="gender" id="gendermale" value="male"/>男

       <input type="radio" name="gender" id="genderfemale" value="female"/>女

OGNL表达式之$号

 $号的作用

      在国际化资源文件中,引用OGNL表达式(先不讲)

      在Struts2配置文件中,引用OGNL表达式

 举例

      ognl.xml配置文件

       <action name="ognlAction_*" class="cn.itcast.ognl.OgnlAction" method="{1}">

              <result name="success">/ognl/ognl.jsp?username=${#request.username}</result>

       </action>

       在ognl.jsp中获取携带的参数:

       <s:property value="%{#parameters.username[0]}"/>

OGNL表达式之%号

 $号的作用

      “%”符号的作用是在当Struts2标签的属性值为OGNL表达式时OGNL表达式却被理解为字符串类型原样输出时,用于通知执行环境%{}里的是OGNL表达式。 

 举例

      Struts2中的textfield标签主要用于在页面中显示一个文本输入框数据。类似input 

      <s:textfield value="#request.username"></s:textfield>

      此时#request.username被理解为一个普通的字符串,因此直接显示。因为这里脱离了

      运行OGNL的环境即:<s:property value="OGNL表达式"/>环境。

      通知运行环境将#request.username以OGNL表达式运行:

      <s:textfield value="%{#request.username}"></s:textfield>

 总结

       为了方便使用%{}我们可以在任何地方都直接添加%{}来确保运行OGNL表达式:

       <s:property value="%{#request.username}"/>

package com.xp.ognl;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

/**
* struts的数据流转
*/
public class OgnlDemo2 extends ActionSupport{
// 根元素值
private User user = new User(100,"Jacks");
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {

ActionContext ac = ActionContext.getContext();
// 映射数据
ac.getContextMap().put("request_data", "request_data");
// 数据存储request
// Map<String,Object> map = (Map<String, Object>) ac.get("request");
// map.put("request_data", "request_data");
// map.put("cn", "China");

ac.getSession().put("Session_data", "Session_data");
ac.getApplication().put("Application_data", "Application_data");
// 二、值栈对象的存储数据的原理
ValueStack vs = ac.getValueStack();
/***************操作根元素的几种方法*****************/
// 设置数据: 入栈
//vs.push(new User(1002,"Tom")); // 栈顶
//vs.pop(); // 移除栈顶元素
// 如何存储? map结构存储
//vs.set("user1", new User(1,"Jacky1"));
//vs.set("user2", new User(2,"Jacky2"));
return super.execute();
}
// 一、获取值栈对象的2种方式
private void getVs() {
// 获取值栈对象,方式1:
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");

// 获取值栈对象,方式2:
ActionContext ac = ActionContext.getContext();
ValueStack vs2 = ac.getValueStack();

System.out.println(vs1 == vs2);//true
}
}
3.测试迭代标签
package com.xp.ognl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class OgnlDemo3 extends ActionSupport{
@Override
public String execute() throws Exception {

// 测试迭代标签

List<User> list = new ArrayList<User>();
Map<Integer,User> map = new HashMap<Integer, User>();

// 初始化
for (int i=1; i<11; i++) {
User user = new User(i,"Jack" + i);

list.add(user);
map.put(user.getId(), user);
}

// 保存
ActionContext.getContext().getContextMap().put("list", list);
ActionContext.getContext().getContextMap().put("map", map);
return super.execute();
}
}

4.常用标签

property标签

property标签用于输出指定值:

<s:propertyvalue=“#name" default="adefault value" />    

    *default:可选属性, 如果需要输出的属性值为null,则显示该属性指定的值

     *  escape:可选属性,指定是否格式化HTML代码。

     *  value:   可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。

例子 :

<s:property/>:输出栈顶的值

    输出: username=username_valueStack, msgxx=msg_valueStack

   <s:property value="%{'<hr> hr的使用'}" escape="false"  />

    输出:<hr> hr的使用

注:escape=“false”时,hr作为html标签使用
 set标签

set标签用于将某个值放入指定范围。
var:变量的名字,name,id和var表达的含义是一样的,name,id被var替代
scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或
action。如果没有设置该属性,则默认放置在action中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
push标签

push:将对象放入栈顶,不能放入其他范围,当标签结束,会从栈顶删除。

     value:要push到堆栈中的值 。

例子:    

   <s:pushvalue="#request.username">

          <s:property/>

    </s:push>

    <br>

     测试删除: <s:property/>
 bean标签

bean标签: 实例化一个符合JavaBeans规范的class,标签体内可以包含几个Param元素,用于调用setter方法给此class的属性赋值.
name:要被实例化的class名字(必须符合JavaBeans规范)
var: 赋给变量的值.放置在request作用域中
如果没有设置该属性,则对象被放置到栈顶
例子:

<s:bean  name="com.xp.bean.Person"var="myperson">
<s:paramname="name" value="%{'zhang'}"></s:param>
<s:paramname="age" value="34"></s:param>
</s:bean><br>
<s:propertyvalue="#myperson.name"/>
 action标签
Action:通过指定命名空间和action名称,该标签允许在jsp页面直接调用Action
name:action名字(不包括后缀,如.action)
namespace:action所在命名空间
executeResult:Action的result是否需要被执行,默认值是false不执行
例子:
<packagename="ognl"  namespace="/ognl" extends="struts-default" >
<actionname="ognlAction_*" class="cn.itcast.ognl.OgnlAction"method="{1}">
<resultname="ognl">/ognl/ongl.jsp?msg=${msgxx}</result>
</action>
</package>
<s:actionname="ognlAction_test" namespace="/ognl"executeResult="true" />
 iterator标签
Iterator:标签用于对集合进行迭代,这里的集合包含List、Set和数组。
value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
var:    可选属性,引用变量的名称.
status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法:
intgetCount(),返回当前迭代了几个元素。
intgetIndex(),返回当前迭代元素的索引。
booleanisEven(),返回当前被迭代元素的索引是否是偶数
booleanisOdd(),返回当前被迭代元素的索引是否是奇数
booleanisFirst(),返回当前被迭代元素是否是第一个元素。
booleanisLast(),返回当前被迭代元素是否是最后一个元素。
<s:iteratorvalue="allList">
<s:propertyvalue="name"/><br>
</s:iterator>
<s:iteratorvalue="allList" var="person" begin="2"end="7"  step="2">
<s:propertyvalue="#person.name"/><s:propertyvalue="#person.age"/><br>
</s:iterator>
<s:iteratorvalue="allList" status="st">
st.getCount():<s:propertyvalue="#st.count"/>   
st.getIndex():<s:propertyvalue="#st.index"/>   
st.isEven():<s:property value="#st.even"/>  
st.isOdd():<s:propertyvalue="#st.odd"/>  
st.isFirst:<s:propertyvalue="#st.first"/>  
st.isLast():<s:propertyvalue="#st.last"/><br>
</s:iterator>
<tableborder="1">
<s:iteratorvalue="allList" var="person" status="st">
<trclass=<s:property value="#st.even?'even':'odd'"/>  >
<td><s:propertyvalue="#person.name"/></td>
</tr>
</s:iterator>
</table>
if/elseif/else标签

if/elseif/else  基本的流程控制.‘If’标签可单独使用也可以和‘Else If’标签和(或)一个多个‘Else’一起使用


<s:if test="#age==23">

   23

</s:if>

<s:elseif test="#age==21">

   21

</s:elseif>

<s:else>

   都不等

</s:else>


url标签

url:该标签用于创建url,可以通过"param"标签提供request参数.

     value:如果不提供就用当前action,使用value后缀必须加.action

     action:用来生成url的action,如果没有则使用value

     namespace:命名空间

     var:引用变量的名称.

    使用action<br>

    <s:urlaction="ognlTagAction_test" namespace="/ognl"var="myurl">

        <s:param name="name" value="%{'张老师'}"></s:param>

        <s:param name="id" value="12"></s:param>

   </s:url>

    <ahref='<s:property value="#myurl" />' >xxxx</a><br>

    <ahref='<s:property value="%{#myurl}" />' >xxxx</a><br>

   

    使用value<br>

    <s:urlvalue="ognlTagAction_test.action" namespace="/ognl"var="myurl">

        <s:param name="id" value="12"></s:param>

        <s:param name="cnname" value="%{'zhang'}"></s:param>

   </s:url>

    <ahref='<s:property value="#myurl" />' >xxxx</a><br>

ognl操作集合







使用ognl操作map 

  ognl用多种方式使用#号,每种是不同的.动态map对于动态单选按扭组很有用.

  创建map与创建list语法很相似,不同的是map前需要加"#"号.

<s:iterator value="#{'key01':'value01','key02':'value02'}">

        <s:property/>   <br>

   </s:iterator>

  

   <s:iterator value="#{'key01':'value01','key02':'value02'}">

        key=<s:property value="key"/>   value=<s:property value="value"/> <br>

   </s:iterator>

   

   

   <s:iterator value="#{'key01':'value01','key02':'value02'}" var="map">

        key=<s:property value="#map.key"/>   value=<s:property value="#map.value"/> <br>

   </s:iterator>

UI标签

 表单标签将在 HTML 文档里被呈现为一个表单元素

 使用表单标签的优点:

 表单回显

 对页面进行布局和排版

 标签的属性可以被赋值为一个静态的值或一个 OGNL 表达式. 如果在赋值时使用了一个 OGNL 表达式并把它用 %{} 括起来, 这个表达式将会被求值.

表单标签的共同属性











label 标签



textarea 标签



checkbox 标签

l checkbox 标签将呈现为一个HTML 复选框元素.

l 与其他HTML 输入元素类似, 当包含着一个单选框的表单被提交时, 这个单选框按钮在 HTTP 请求里增加一个请求参数. 如果某个单选框被选中了, 它的值将为 true, 但如果该单选框未被选中, 在请求中就不会增加一个请求参数. checkbox 标签解决了这个局限性, 它采取的办法是为单选框元素创建一个配对的不可见字段









Radio标签

radio标签将呈现为一组单选按钮, 单选按钮的个数与程序员通过该标签的 list 属性提供的选项的个数相同.

一般地, 使用 radio 标签实现 “多选一”, 对于 “真/假” 则该使用 checkbox标签.









如果集合为MAP

<s:select name="map" list="#{1:'瑜珈用品',2:'户外用品',3:'球类',4:'自行车'}" listKey="key" listValue="value" value="1"/>

生成如下html代码:

<select name="map" id="map">

    <option value="1" selected="selected">瑜珈用品</option>

    <option value="2">户外用品</option>

    <option value="3">球类</option>

    <option value="4">自行车</option>

</select>

主题

主题: 为了让所有的 UI 标签能够产生同样的视觉效果而归集到一起的一组模板. 即风格

相近的模板被打包为一个主题

 1、simple: 把 UI 标签翻译成最简单的 HTML 对应元素, 而且会忽视行标属性

 2、xhtml: xhtml 是默认的主题. 这个主题的模板通过使用一个布局表格提供了一

      种自动化的排版机制. (默认值)

 3、css_xhtml: 这个主题里的模板与 xhtml 主题里的模板很相似, 但它们将使用 css

      来进行布局和排版

 4、ajax: 这个主题里的模板以 xhtml 主题里德模板为基础, 但增加了一些 Ajax 功能. 

 修改主题:

        A、通过 UI 标签的 theme属性(只适用于当前的标签)

    <s:textfield name="username"  label="用户名“

                                                 theme="simple"></s:textfield>

B、在一个表单里, 若没有给出某个 UI 标签的 theme 属性, 它将使用这个表单的主题

     (适用于整个form标签)

    <s:form  action="" method="post" namespace="/ui“    theme="simple">

C、修改 struts.properties 文件中的 struts.ui.theme 属性. (适用整个环境)

         <!-- 设置ui标签的主题 -->

         <constant name="struts.ui.theme" value="simple"></constant>

优先级:A>B>C
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息