Struts2从后端向前端传递数据和OGNL访问用户自定义静态方法(五)

简介: Struts2从后端向前端传递数据和OGNL访问用户自定义静态方法(五)

第三章时我们介绍了Struts2从前端获取数据,封装到后端,在第四章时做了两个小项目来说明从前端获取数据,然而在获取数据时,


用的是ServletActionContext.getRequest().setAttribute(String key,Object value) ,


即用的的Servlet中的HttpServletRequest类进行相应的封装,耦合度太高。


Struts2 既然提供了自己的方法来获取数据,那么相应的也会提供自己的方法来展示数据。


最常用的技术就是OGNL表达式和值栈。 在显示数据时,用到了struts2的标签和OGNL表达式,其中el表达式增强了Request的底层getAttribute()方法,所以el表达式也可以访问后端封装的数据。


OGNL 中获取的数据,是从 Stack Context 中获取数据。 其中,值栈 Value Stack 也属于 Stack Context, 只不过是 Stack Context 最上面的一层。 即Struts2 把所有的数据,都放置到 Stack Context里面,其中 Stack Context最上面的一块区域叫做 Value Stack, Value Stack 里面的数据,可以直接取出, Stack Context 里面的数据,不能直接取出, 必须通过 # 号才可以取出。


一. 封装数据


一.一 封装基本数据类型用setter(从前端–>后端)和getter(从后端到前端)方法


Struts2中常用的单个类型有String类型(String不属于8种基本数据类型)和Integer (最好使用包装类Integer)类型


一.一.一 创建Action ,为 SingleAction


新建一个SingleAction,放置基本的数据类型


package com.yjl.web.action;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.log4j.Logger;
/**
* @author 两个蝴蝶飞
* @version 创建时间:2018年8月24日 上午9:15:50
* @description 单个的数据类型的封装,如Integer 和String
*/
public class SingleAction extends ActionSupport{
    private static final long serialVersionUID = -6264461713221609298L;
  private Logger logger=Logger.getLogger(SingleAction.class);
  private Integer age;
  private String name;
  //定义一个属性后,最好setter和getter方法均实现
  public Integer getAge() {
    return age;
  }
  public String getName() {
    return name;
  }
  public String getData() {
    age=24;
    name="两个蝴蝶飞";
    return SUCCESS;
  }
}


一.一.二 配置 struts.xml


 <package name="data" extends="struts-default" namespace="/">
    <action name="Single_*" class="com.yjl.web.action.SingleAction" method="{1}">
        <result name="success">/WEB-INF/content/showData.jsp</result>
    </action>
</package>


一.一.三 编写 /content/showData.jsp 页面


前端显示的时候,showData.jsp页面的代码如下:


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!--需要引入struts的标签库,默认都添加过了-->
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--struts2 提供的标签-->
  姓名: <s:property value="name"/> <br/>
  年龄: <s:property value="age"/>
</body>
</html>


在输入请求: http://localhost:8080/Struts_Data/Single_getData.action 后,


会显示出结果:


20200609112607263.png


这是 struts2 标签库,通过 getter() 方法,来获取数据的。


一.二 封装数据到 request,session,application 域里面


有的时候,这个属性并不是表单中或者实体中的数据,只是一个单纯的提示信息,如message,主要用于提示登录信息。


这个时候就不用麻烦的实现它的setter和getter方法了,可以直接用ActionContext类将其放在类似于request,session的map集合里面。


一.二.一 放置数据


在后端Action 的getData()方法中:


String message="用户名或者密码错误";
//放在request域中
ActionContext.getContext().put("message",message);
//放在application域中
//ActionContext.getContext().getApplication().put("message",message);
//放在session域中
//ActionContext.getContext().getSession().put("message",message);


运用的是第一种方式, ActionContext() 来获取 Servlet API ,用于存储数据。


一.二.二 前端通过 EL 获取数据


在前端获取时,用el表达式获取


显示错误的信息,取出时EL时用: ${message} <br/>


一.三 封装List让其显示到前端


一.三.一 放置数据


    public String getData() {
    List<String> allList=new ArrayList<String>();
    allList.add("两个蝴蝶飞");
    allList.add("慧芳");
    allList.add("正伟");
    //放置时用值栈里面 
    ActionContext.getContext().getValueStack().set("allList",allList);
    return SUCCESS;
  }


放在栈顶的用getValueStack().push(Object) 方法,这个常用于放置单个对象。


getValueStack().set(key,Object) 常常用于放置集合。


一.三.二 获取数据


如果不是放在栈顶,只是一个普通的变量,可以用set方法,进行设置属性。


  <!--设置标签库-->
  <%@ taglib uri="/struts-tags" prefix="s"%>
    <s:iterator value="allList" var="name">
      <s:property value="#name"/><br/>
  </s:iterator>


一.四 封装Map集合到前端(如入学年份)


一.四.一 放置数据


    public String getData() {
    Map<Integer,String> yearMap=new HashMap<Integer,String>();
    yearMap.put(2014,"2014级学生");
    yearMap.put(2015,"2015级学生");
    yearMap.put(2016,"2016级学生");
    yearMap.put(2017,"2017级学生");
    //放置时用值栈  在一次性传递数据到前端时,会有很多的数据,不要都放在栈顶ValueStack中.
    ActionContext.getContext().getValueStack().set("yearMap",yearMap);
    return SUCCESS;
  }


一.四.二 获取数据


在前端时,显示时只需要key,value即可,会自动解析。


    <s:iterator value="yearMap">
    <s:property value="key"/>-------><s:property value="value"/> <br/>
  </s:iterator>


一.五 封装单个 java Bean 对象到前端(用Push方法放在栈顶)


一.五.一 放置数据


    public String getData() {
    User user=new User();
    user.setName("莉莉");
    user.setAge(25);
    user.setSex("女");
    user.setRelation("二姐");
    ActionContext.getContext().getValueStack().push(user);
    return SUCCESS;
  }


一.五.二 获取数据


  姓名:<s:property value="name"/>
  年龄:<s:property value="age"/>
  性别:<s:property value="sex"/>
  关系:<s:property value="relation"/>


有时,为了简便属性,常用EL表达式取出


  姓名:${name}
  年龄:${age}
  性别:${sex}
  关系:${relation}


用 EL 表达式取出时,准确地来说,是从 StackContext 里面取出的数据。


一.五.二 获取对象属性数据


在实际的开发项目中,实体与实体之间是有一定的关联的,如User 中会存在Class对象,表示这个用户属于哪一个班级,


那么在取出属性数据的时候,如取出Class中的name值,可以用.(点)的方式取出


在user 对象里面,可以通过

<s:property value=“class.name”/> 或者 ${class.name} 来获取数据。


可以进行一直的连续点击 如 user.class.speciality.name; 学生的班级的专业的名称


一.六 封装List 对象到前端


最常用的操作还是查询,查询出所有符合条件的对象,这是非常常用。(用第四章项目的UserService中的静态模拟数据)


一.六.一 设置数据


    public String getData() {
    UserService userService=new UserService();
    List<User> userList=userService.findAll();
    ActionContext.getContext().getValueStack().set("userList",userList);
    return SUCCESS;
  }


一.六.二 获取数据


在前端页面中,


可以用${user.name} el 表达式


<tbody>
  <s:iterator value="userList" var="user">
      <tr>
        <td>${user.name}</td>
        <td>${user.sex}</td>
        <td>${user.age}</td>
        <td>${user.relation}</td>
        <td>
          <a href="#">查看详情</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          <a href="#">修改</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          <a href="#">删除</a>
      </tr>
  </s:iterator>
</tbody>


也可以用 struts2提供的 property 属性标签:


<td><s:property value="#user.name"/></td>


形式。


有时候为了简化方便,也会省略 var=“user” (只放置在Value Stack 里面,用完就删除)


<tbody>
  <s:iterator value="userList">
     <tr>
      <td>${name}</td>
      <td>${sex}</td>
      <td>${age}</td>
      <td>${relation}</td>
      <td>
        <a href="#">查看详情</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <a href="#">修改</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <a href="#">删除</a>
    </tr>
  </s:iterator>
</tbody>


建议不要省略var=“user” .


虽然在开发中多写这一个var="user"麻烦了一些,但是规范性和可读性高了一些。


在显示user时,var=“user”,在显示class时,var=“class”,

这样在u s e r . n a m e , {user.name} ,user.name,{class.name} 时会增加可读性, ${name}就不明所以了。


重启服务器,显示:


20200609112634853.png


常用的基本的类型就这些了, Map<String,List>等形式是不常用的,就不讲解了。


二. OGNL表达式的强大之处


二.一 直接调用字符串中的方法


        <div class="row">
      ognl显示字符串的长度:<s:property value="'两个蝴蝶飞'.length()"/><br/>
      ognl字符串转换成大写显示:<s:property value="'hello world'.toUpperCase()"/>
    </div>


二.二 OGNL访问系统包下的静态属性和方法


如访问 math包下的 PI静态属性 和 abs() 静态方法


        <div class="row">
      Math中的PI静态属性:<s:property value="@java.lang.Math@PI"/><br/>
      Math中的abs静态方法:<s:property value="@java.lang.Math@abs(-3)"/><br/>
    </div>


访问后展示结果:


20200609112658691.png


二.三 访问自定义的静态属性和方法


如果stuts2内置的方法不够使用时,用户可以自己定义相应的属性和方法。


二.三.一 创建标签类


在pojo包下新建一个MyOgnl类,里面有静态属性,静态无参方法,静态有参方法


package com.yjl.pojo;
/**
* @author 两个蝴蝶飞
* @version 创建时间:2018年8月24日 上午10:44:37
* @description ongl执行静态方法
*/
public class MyOgnl {
  public static String NAME="两个蝴蝶飞";
  public static String defaultMethod1() {
    return "我是一个Java程序员";
  }
  public static String defaultMethod2(String str) {
    if(str!=null&&!"".equals(str)) {
      return str+"长度是:"+str.length();
    }else {
      return "字符串为空,长度是:0";
    }
  }
}


二.三.二 struts2.xml 配置 struts.ognl.allowStaticMethodAccess 属性。


需要在struts.xml配置struts.ognl.allowStaticMethodAccess的值为true,允许访问. 默认为false


  <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>


二.三.三 前端页面展示


在showData.jsp页面上


<div class="row">
    访问静态属性:
    <s:property value="@com.yjl.pojo.MyOgnl@NAME"/> <br/>
    访问静态无参方法:
    <s:property value="@com.yjl.pojo.MyOgnl@defaultMethod1()"/> <br/>
    访问静态有参方法:
    <s:property value="@com.yjl.pojo.MyOgnl@defaultMethod2('两个蝴蝶飞')"/> <br/>
</div>


访问静态属性,形式为: @类全限定名称@静态属性,


访问静态方法,形式为: @类全限定名称@方法(), @类全限定名称@方法(参数1,参数2)


展示页面如下所示:


2020060911272437.png


三. 检测每个Action对象里面只有一个值栈对象


在访问Action时,每一次访问,都会创建一个Action对象。 它是多实例的。 与Servlet不一样,Servlet只是在第一次访问时进行实例化。 每一个Action对象都只有一个ValueStack值栈。


public String getData() {
  ActionContext ac=ActionContext.getContext();
  ValueStack v1=ac.getValueStack();
  ValueStack v2=ac.getValueStack();
  logger.info(v1==v2); //true
  return SUCCESS;
}


20200609112741336.png


谢谢您的观看!!!

相关文章
|
28天前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
134 5
|
5月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
510 1
|
6月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
414 70
|
5月前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
334 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
7月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
345 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
9月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
316 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
4月前
|
人工智能 监控 前端开发
AI工具:前端与后端的终极对决?谁将成为新时代的宠儿?
深入探讨AI工具对前端和后端开发的具体影响、各自的机遇与挑战,并分析未来开发者如何驾驭AI,实现能力跃迁。
215 0
|
7月前
|
前端开发 算法 NoSQL
前端uin后端php社交软件源码,快速构建属于你的交友平台
这是一款功能全面的社交软件解决方案,覆盖多种场景需求。支持即时通讯(一对一聊天、群聊、文件传输、语音/视频通话)、内容动态(发布、点赞、评论)以及红包模块(接入支付宝、微信等第三方支付)。系统采用前后端分离架构,前端基于 UniApp,后端使用 PHP 框架(如 Laravel/Symfony),配合 MySQL/Redis 和自建 Socket 服务实现高效实时通信。提供用户认证(JWT 集成)、智能匹配算法等功能,助力快速上线,显著节约开发成本。
175 1
前端uin后端php社交软件源码,快速构建属于你的交友平台
|
6月前
|
监控 前端开发 小程序
陪练,代练,护航,代打小程序源码/前端UNIAPP-VUE2.0开发 后端Thinkphp6管理/具备家政服务的综合型平台
这款APP通过技术创新,将代练、家政、娱乐社交等场景融合,打造“全能型生活服务生态圈”。以代练为切入点,提供模块化代码支持快速搭建平台,结合智能匹配与技能审核机制,拓展家政服务和商业管理功能。技术架构具备高安全性和扩展性,支持多业务复用,如押金冻结、录屏监控等功能跨领域应用。商业模式多元,包括交易抽成、增值服务及广告联名,同时设计跨领域积分体系提升用户粘性,实现生态共生与B端赋能。
557 12
|
9月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
283 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

热门文章

最新文章

  • 1
    我尝试了所有后端框架 — — 这就是为什么只有 Spring Boot 幸存下来
  • 2
    前端工程化演进之路:从手工作坊到AI驱动的智能化开发
  • 3
    Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
  • 4
    实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
  • 1
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    34
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    93
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    47
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    134
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    112
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    66
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    35
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    67
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    79
  • 10
    Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
    155