本博客为​​这篇博客​​的辅助博客,主要是其中自己写的一些Demo.java代码

目录

​Struts2_day03​

​ongl表达式简单Demo​

​OgnlDemo1.java​

​Struts2框架中使用OGNL表达式​

​demo1.jsp​

​获取到值栈的对象,向值栈中保存数据,从值栈中获取值(前端),EL表达式也获取值栈​

​struts.xml​

​User.java​

​ValueStack1Action.java​

​vs.jsp​

​案例:客户列表​

​CustomerAction.java​

​CustomerService.java​

​CustomerDao.java​

​struts.xml2​

​list.jsp​

​OGNL表达式的特殊的符号简单Demo​

​demo3.jsp​


Struts2_day03

ongl表达式简单Demo

OgnlDemo1.java

package com.itheima.demo1;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

import org.junit.Test;

/**
* 演示OGNL表达式
* @author Administrator
*
*/
public class OgnlDemo1 {

/**
* 测试
* @throws OgnlException
*/
@Test
public void run1() throws OgnlException{
//上下文对象
OgnlContext context = new OgnlContext();
//获取根对象(想取值 默认都是从根对象中取值)
Object root = context.getRoot();
//存储数据
context.put("name", "美美");
//获取值(静态方法) 表达式的写法先不管
Object value = Ognl.getValue("#name", context, root);
System.out.println(value);
}

/**
* Ognl表达式可以调用方法
* @throws OgnlException
*/
@Test
public void run2() throws OgnlException{
//上下文对象
OgnlContext context = new OgnlContext();
//获取根对象(想取值 默认都是从根对象中取值)
Object root = context.getRoot();
//获取值(静态方法) 表达式的写法先不管
Object value = Ognl.getValue("'hanzhuan'.length()", context, root);
System.out.println(value);

}


}

Struts2框架中使用OGNL表达式

demo1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 引入struts2标签库 -->
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- prefix前置名称 uri默认提示的第一个就是 -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'demo1.jsp' starting page</title>
</head>

<body>
<h3>条件:假如值栈中已经存入值了,在JSP页面上从值栈中获取值</h3>
<!--
1.先引入struts2框架提供的标签库,s标签(之前的jstl是c标签)
2.可以使用提供的标签(很多,但只用掌握几个重点使用的即可)
-->
<!-- s:property从值栈中取值的标签 value值写Ognl表达式,根据表达式取值 未找到显示空字符串 -->
解析Ognl表达式(value值),没有显示空:<s:property value="username"/><br>
普通字符串要加''才能输出,如'username':<s:property value="'username'"/><br>
解析方法,如:'username'.length():<s:property value="'username'.length()"/><br>

</body>
</html>

获取到值栈的对象,向值栈中保存数据,从值栈中获取值(前端),EL表达式也获取值栈

struts.xml

<?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="demo1" namespace="/" extends="struts-default">
<!-- 演示利用API获取值栈 -->
<action name="vs1" class="com.itheima.demo2.ValueStack1Action"/>

<!-- 压栈和取值 -->
<action name="save" class="com.itheima.demo2.ValueStack1Action" method="saveAndGet">
<!-- 转发(即默认) 不要重定向 -->
<result name="success">/demo2/vs.jsp</result>
</action>
</package>
</struts>

User.java

package com.itheima.demo2;

public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User() {}

}

ValueStack1Action.java

package com.itheima.demo2;

import java.util.ArrayList;
import java.util.List;

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;

/**
* 演示值栈对象的目录结构
* @author Administrator
*
*/
public class ValueStack1Action extends ActionSupport{

/**
* 1.必须自己初始化
* 2.必须提供get/set才是属性
* 3.Action类对象压栈,可以访问对象,就可以访问对象下的属性
*/
/*private User user=new User("慕容紫英","987654");
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}*/

@Override
public String execute() throws Exception {
//获取值栈对象
/*HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack");
System.out.println(vs); */

/*ActionContext中存在一个Map集合,该Map集合和ValueStack的context是同一个地址
* 可以利用ActionContext来获取ValueStack的context了,更方便,不用记忆struts.valueStack了
*/
//先获取ActionContext(静态方法) 再利用ActionContext获取ValueStack对象
/*ActionContext context = ActionContext.getContext();
ValueStack vs = context.getValueStack();*/
ValueStack vs = ActionContext.getContext().getValueStack();//以后直接这一行就获取值栈对象即可
System.out.println(vs);


//存值
vs.push("aa");//往栈顶压值 底层ArrayList实现
/*首先看栈顶是否是map,
* 若是:
* 把值存入 map集合
* 若不是:
* new HashMap(),把值存入刚new的map,然后将此map压栈
*/
vs.set("key", "value");
vs.set("msg", "美美");
vs.set("info", "天河");

return NONE;
}

/**
* 演示从值栈中获取值
*/
public String saveAndGet() throws Exception {
//获取值栈
ValueStack vs = ActionContext.getContext().getValueStack();
//往值栈中压入值
//vs.push("美美");

//vs.set("msg", "天河");

/*往值栈压对象*/
//创建User对象
//User user = new User("云天河", "12345");
//压栈
//vs.push(user);
//vs.set("user", user);

List<User> ulist=new ArrayList<User>();
ulist.add(new User("熊大", "123"));
ulist.add(new User("熊二", "456"));
ulist.add(new User("熊三", "789"));
//把ulist压入集合
//vs.push(ulist);

vs.set("ulist", ulist);//比较好的方式 可以完全省略关键字 [0].top

/*前面都是push和set都是往root栈中压值 下面介绍往值栈的context栈中压值*/
//从context栈中获取值,底层已经封装了request session等对象(map集合形式) 直接往request中存值,值栈可以获取到它
//HttpServletRequest request = ServletActionContext.getRequest();
//request.setAttribute("msg", "崔浩");//直接就到context栈的某个key为"request"的域中了

//ServletActionContext.getContext().getSession()
//request.getSession().setAttribute("msg", "梦璃");

return SUCCESS;
}

}

vs.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'vs.jsp' starting page</title>
</head>

<body>
<h3>从值栈中获取值</h3>
<!--
0从栈顶开始打印 1栈顶往下一个位置开始打印 (访问的Action类也会压栈 且比值先压) 以此类推
//vs.push("美美");
//<s:property value="[0]"/><br>
<s:property value="[0].top"/><br>
-->

<!--
//栈顶是map集合,通过key获取值
//vs.set("msg", "天河");
<s:property value="[0].top.msg"/>
-->

<!--
值栈放入user对象
//[0].top先取到栈顶对象
//然而强大之处在于下面的"[0].top."关键字可以省略(默认从栈顶开始找 只要你压了,那么肯定会有 ,这就可以省略了)

<s:property value="[0].top.username"/><br>
<s:property value="[0].top.password"/><br>
省略关键字<br>
<s:property value="username"/><br>
<s:property value="password"/><br>
-->


<!--
vs.set("user", user);
对象压入map集合
//同样"[0].top."可以不写 但是user是map的key可不能省略了

<s:property value="[0].top.user.username"/><br>
<s:property value="[0].top.user.password"/><br>
<s:property value="user.username"/><br>
<s:property value="user.password"/><br>
-->

<!--
Action对象属性压栈
自己主动new User压栈

private User user=new User("慕容紫英","987654");
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}

User user = new User("云天河", "12345");
//压栈
//vs.push(user);
vs.set("user", user);

//从栈顶开始查找,找user的属性,显示名称,返回的是最后压栈是自己new的user
<s:property value="user.username"/><br> //自己压栈的
//[1].top获取ValueStack1Action 返回其属性的user对象
<s:property value="[1].top.user.username"/><br> //Action属性

-->

<!--
vs.push(ulist);
栈顶是list集合
先[0].top取到栈顶看看 则
[0].top=>List<User> 获得user集合
[0].top[0]=>list.get(0) 获取第一个User对象
[0].top[0].username=>取得第一个对象的username

<s:property value="[0].top[0].username"/><br>
<s:property value="[0].top[1].username"/><br>
<s:property value="[0].top[2].username"/><br>
-->

<!--
压入的是map集合
<s:property value="ulist"/> //获得栈顶的map "[0].top"省略了
<s:property value="ulist[0]"/> //取得map里第一个对象

<s:property value= "ulist[0].username"/>
-->

<!-- 以上是正常取值 一个个地取 下面讲强大的迭代标签-->
<!-- 迭代的标签 功能和foreach一样
属性:
begin end step 达到普通for循环的效果
重点属性
* value 要迭代的集合,需要从值栈中获取
* var 迭代过程中,遍历对象 (麻烦在var可写可不写)
*var写上,把迭代产生的对象默认压入到context栈中,从context栈取值要加#
*var不写,默认把迭代对象压入到root栈中(取完弹栈)


<s:iterator value="ulist" var="u"> //等价于[0].top.ulist 写var 值被压入context栈中了
<s:property value="#u.username"/>
<s:property value="#u.password"/><br>
</s:iterator>
<hr>
<s:iterator value="ulist"> //不写var 值被压入root栈中了
<s:property value="[0].top.username"/> //[0].top就取到了栈顶对象 正好就是要遍历的单个user,此次的这一个
<s:property value="password"/><br>
</s:iterator>

<!-- 从context栈中取值 注意加#
<s:property value="#request.msg"/> //map的key就是字符串'request' #request是map .key就取值了
<s:property value="#session.msg"/>
<s:property value="#parameters.id"/> //可以直接获取访问的超链接中的参数值 如/save.action?id=20 会打印出来20
<s:property value="#attr.msg"/> //最小的域中找值

-->

<!--
在jsp页面中可以使用el和jstl标签库获取值栈的值 (eclipse需要jstl.jar和standard.jar包)
因为使用了装饰者模式,所以el/jstl也可以取到值 getAttribute方法增强了
查看源代码发现: request = prepare.wrapRequest(request); 将request增强了
getAttribute 增强:先判断取没取到值,没有取到就从值栈里去取
-->

<c:forEach items="${ulist }" var="user">
${user.username }--${user.password }<br>
</c:forEach>


<!-- 在JSP页面上,查看值栈的内部结构 -->
<s:debug></s:debug>

</body>
</html>

案例:客户列表

CustomerAction.java

package com.itheima.action;

import java.util.List;

import com.itheima.domain.Customer;
import com.itheima.service.CustomerService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.util.ValueStack;

/**
* 客户的控制器
* @author Administrator
*
*/ //这个Action都是关于客户的操作
public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{

//千万注意必须要手动实例化一个对象 差点忘了
private Customer customer=new Customer();//对customer的添加,修改,不论什么功能,一提交就帮你封装了
@Override
public Customer getModel() {
return customer;
}

/**
* 保存客户
* @return
*/
public String save(){
//保存客户
new CustomerService().saveCustomer(customer);//简直不要太简单 仔细看看3层 太简单了 全是调用save ssm岂不是更简单了,哈哈哈哈哈或
return "alist";
}

/**
* 查询所有客户
*/
public String list(){
System.out.println("customerAction执行了");
//获取客户列表
List<Customer> clist = new CustomerService().findAll();
//获取值栈
ValueStack vs = ActionContext.getContext().getValueStack();
//压入值栈 一般集合使用set 对象使用push 这样比较简单
vs.set("clist", clist);
return "list";
}



}

CustomerService.java

package com.itheima.service;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.itheima.dao.CustomerDao;
import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;

/**
* 客户的业务层
* @author Administrator
*
*/
public class CustomerService {

/**
* 查询所有客户
*/
public List<Customer> findAll(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
List<Customer> clist=null;
try {
clist=new CustomerDao().findAll();
tr.commit();//commit在下面 没碎觉不能敲代码 太粗心了 脑汁不够用
return clist;//下面return null;这里一定要return
} catch (Exception e) {
tr.rollback();
e.printStackTrace();
}

return null;//返回的是cList
}


}

CustomerDao.java

package com.itheima.dao;

import java.util.List;

import org.hibernate.Session;

import com.itheima.domain.Customer;
import com.itheima.utils.HibernateUtils;

public class CustomerDao {

/**
* 查询所有客户
* @return
*/
public List<Customer> findAll() {
Session session = HibernateUtils.getCurrentSession();
return session.createQuery("from Customer").list();
}

}

struts.xml2

<?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="crm" namespace="/" extends="struts-default">

<!-- 配置拦截器 下面每个Action都要引入-->
<interceptors>
<interceptor name="UserInterceptor" class="com.itheima.interceptor.UserInterceptor"></interceptor>
</interceptors>

<!-- 配置全局跳转页面 在本包(crm)内有效-->
<global-results>
<result name="login">/login.htm</result>
</global-results>

<!-- <default-interceptor-ref name=""></default-interceptor-ref> 能不能所有的页面都不访问-->

<!-- 配置用户模块action --> <!-- 通配符法真不错! -->
<action name="user_*" class="com.itheima.action.UserAction" method="{1}">
<result name="login">/login.htm</result>
<result name="success">/index.htm</result>
<interceptor-ref name="UserInterceptor">
<!-- login方法不拦截 "excludeMethods"别写错了-->
<param name="excludeMethods">login</param><!-- 就是配置一个javaBean属性的值 -->
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</action>

<!-- 客户模块 -->
<action name="customer_*" class="com.itheima.action.CustomerAction" method="{1}">
<result name="list">/jsp/customer/list.jsp</result>
<!-- 转发到列表Action 写为Action配置的name:customer-->
<result name="alist" type="chain">customer_list</result>
<interceptor-ref name="UserInterceptor"/>
<interceptor-ref name="defaultStack"/>
</action>

</package>


</struts>

list.jsp

<html>
<head>
<TITLE>客户列表</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<body>
<!-- 以后做项目 前端还是不变 用el表达式做 比较简单 后端框架也都往el表达式这兼容了 -->
<!-- jstl也可以获取值栈 -->
<%-- <c:foreach items="${clist }" var="customer">
<tr
style="font-weight: normal; font-style: normal; background-color: white; text-decoration: none">
<td>${customer.cust_name }</td>
<td>${customer.cust_level }</td>
<td>${customer.cust_source }</td>
<td>${customer.cust_linkman }</td>
<td>${customer.cust_phone }</td>
<td>${customer.cust_mobile }</td>
<td>
<a href="${pagecontext.request.contextpath }/customerservlet?method=edit&custid=${customer.cust_id}">修改</a>
  
<a href="${pagecontext.request.contextpath }/customerservlet?method=delete&custid=${customer.cust_id}">删除</a>
</td>
</tr>

</c:foreach> --%>

<!-- struts2标签迭代 -->
<s:iterator value="clist"><!-- 压入栈顶 现在栈顶就是clist集合 -->
<tr
style="font-weight: normal; font-style: normal; background-color: white; text-decoration: none">
<td><s:property value="cust_name"/> </td>
<td><s:property value="cust_level"/> </td>
<td><s:property value="cust_source"/> </td>
<td><s:property value="cust_linkman"/> </td>
<!-- el表达式也还可以用 -->
<td>${customer.cust_phone }</td>
<td>${customer.cust_mobile }</td>
<td>
<a href="${pagecontext.request.contextpath }/customerservlet?method=edit&custid=<s:property value="cust_id"/>">修改</a>
  
<a href="${pagecontext.request.contextpath }/customerservlet?method=delete&custid=<s:property value="cust_id"/>">删除</a>
</td>
</tr>
</s:iterator>
</body>

 

OGNL表达式的特殊的符号简单Demo

demo3.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'demo3.jsp' starting page</title>
</head>

<body>
<h3>编写表单</h3>
<form action="" method="post">
性别: <input type="radio" name="sex" value='男'>  <input type="radio" name="sex" value="女">
</form>

<h3>使用struts2的UI标签</h3>
<s:form action="" method="post">
<%-- 性别:<s:radio name="sex" list="{'男','女'}"/><br> --%>
性别:<s:radio name="sex" list="#{'1':'男','2':'女'}"/>
</s:form>

</body>
</html>