zoukankan      html  css  js  c++  java
  • 【Struts2】Ognl表达式

    5).OGNL表达式-操作数据空间

    O(Object) G(Graphic) N(Navigation) L(Language) 对象 图 导航语言
    作用:通过表达式方式(非Java代码)的方式操作指定数据。
    特点:(对比EL)
    ①可以调用方法
    ②可以存入数据(绑定数据)
    OGNL可以操作数据空间(对象):
    导入jar: ognl.jar
    ① ognl向root区的对象中存入数据
    Ognl.setValue("root区的对象的属性名",root区对象,值);
    ②ognl从root区的对象中获取数据
    Object ognl表达式获取的结果 = Ognl.getValue("root区对象的属性名",root区对象);
    ③调用方法
    语法: Ognl: "对象.方法名(参数)"
    注意: 表示字符串 "zxxx"   '1000'(如果ognl外部使用双引号,内部字符串使用单引号)
    ④数学运算和逻辑运算
    + - * / % == != ! && || 
    注意: (1==“1”)忽略数据类型;(10/3结果为3) 数字除运算, 按照java运算规则计算
    ⑤Ognl访问List集合类型数据
    语法: ognl: "list集合[i]"
    ⑥Ognl访问Map集合元素
    语法: ognl:  
    			"map对象.key"  		key不能是纯数字内容。
        		"map对象['key']" 		key可以数字或者字符串。
    ⑦Ognl从context区域获取数据
    重点: context区域是一个map结构
    	key是字符串、value对象类型
    语法: Ognl表达式: "#key"   context中map的value
    测试方法: Ognl.getValue("ognl表达式",放入context区的map,root对象);
    

    6).OGNL表达式-值栈(ValueStack)、Struts2值栈的使用+Struts2标签库[重点]

    (1)值栈 ValueStack(类名)
    作用:
    封装ognl的root和context
    使用Ognl表达式访问值栈内部root区中的对象,context中map的key对应的value
    值栈相关api:
    ①获得值栈对象
    ValueStack vs = ActionContext.getContext().getValueStack();
    ②获得root(栈)
    CompoundRoot root = vs.getRoot();
    ③向root中存入对象
    root.push(作为root对象);
    ④获得context
    Map<String,Object> context = vs.getContext();
    ⑤如果想context中存入数据
    context.put("key",值);
    ⑥值栈对象提供方法  vs.findValue("ognl表达式"), 使用ognl获得值栈中的数据。
    			获取root区属性值:			vs.findValue(“对象属性”);
    			获取ContextMap区value:		vs.findValue(“#key”);
    (2)Struts2值栈的使用+Struts2标签库[重点]
    Struts2对值栈的管理
    ①值栈:
    Context区(数据结构  Map)[重点]
        "request"    	RequestMap(相当于HttpServletRequest作用域)
        "session"    	SessionMap(相当于HttpSession作用域)
        "application" 	ApplicationMap(相当于ServletContext作用域)
    Root区(数据结构  栈 Stack)
    	将当前的Action对象放在root区栈顶。
    ②struts2标签库:
    使用:
    a.引入标签库:<%@taglib uri="/struts-tags" prefix="s" %>
    b.使用property标签:<s:property value="ognl表达式"></s:property>
    作用: 
    a.执行ognl获得数据
    b.将结果展示给浏览器
    ③总结:
    a. 向RequestMap中存入值
    	Map<String,Object> requestMap =  (...)vs.getContext().get("request");
    	requestMap.put("名字key",值);
        通过Ognl表达式访问RequestMap(相当于request作用域)
        OGNL: "#request.requestmap中的key"
    b. 向SessionMap存入值
        Map<String,Object>  sessionMap = (..)vs.getContext().get("session");
        sessionMap.put("key",value)
        通过Ognl表达式访问SessionMap(相当于session作用域)
        OGNL: "#session.sessionMap中的key"
    c. 通过Ognl表达式访问当前的Action的属性值:
        注意: Action生命周期是一次请求过程。(请求转发)
    OGNL: "Action的属性名"
    

    7).OGNL表达式-常用的Struts2标签、及在struts.xml中使用

    (1)常用Struts2标签(在JSP中使用OGNL)
    ①property
       语法: <s:property value="OGNL表达式,值栈的root获取值,context获得值"/>
       作用:
       	a.执行ognl表达式,获得数据
    b.讲结果显示给浏览器。
       常用:
       <s:property value="Action的属性名"/>   [获得action的属性值]
       <s:property value="#request.requestMap的key"/>  [获得相当于request作用域的requestMap的值]
       <s:property value="#session.sessionmap的key"/>  [获得相当于session作用域的sessionMap的值]
       补充:
       	<s:property/>   [获得的值栈的root区栈顶的对象]
    ②格式化日期
       <s:date name="ognl获得要格式化显示的日期" format="设置日期格式"/>
       日期格式:
       年yyyy     月MM     日dd
    ③判断
       语法: 	<s:if test="OGNL获得数据并逻辑判断1">条件1成立</s:if>
       		<s:elseif test="ognl条件2">条件2成立</s:elseif>
       		<s:else>都不成立</s:else>
    ④遍历ListJ集合
      <s:iterator value="OGNL被遍历的集合">
    <s:property/>当前被遍历的对象:被遍历的当前对象被放在了root区的栈顶位置
          <s:property value="当前对象的属性名"/>当前被遍历的对象的属性
      </s:iterator>
      作用: a. value属性遍历集合;b. 遍历过程中,每个被遍历的当前对象,暂时放在值栈的root区的栈顶。
      属性介绍:
     	 	value: 			OGNL获得被遍历集合
    begin: 			起始下标
      		end: 			截止下标
      		step: 			步长      	[配合  begin="0"]
     		status="vs"		(vs.index(下标序号);   vs.count(排序序号))
      注意: 将vs存入值栈的context中。key="vs"
    ⑤遍历Map
      <s:interator value="ognl获得map">
      		将遍历的每个当前对象(Map.Entry key+value),放入root栈顶。
          	展示key:  <s:property value="key"/>
          	获得value: <s:property value="value"/>
      </s:interator>
    ⑥url重写
    <s:url value="请求资源的路径"></s:url>
        作用:
     	a. 自动补全 "/项目名"
          b. cookie被禁用的请情况下对url进行重写。(url;jsessionid=1234asdd1234asd);
    ⑦action请求标签
       语法:  s:action name="" namespace="" executeResult="true"></s:action>
       作用:向action发起请求,接收服务器响应的结果。
       属性:
       name: 		请求的action的name
       namespace: 	请求的action的命名空间namespace
       executeResult: 	是否包含action的执行结果页面。
    (2)Struts2标签在struts.xml中使用
    struts.xml书写OGNL表达式
    ognl在struts.xml获得root中当前Action的属性名,作用域对应的map中的值。 
    语法: ${ognl表达式}
    在跳转路径中使用超链接传值:
    

    8).OGNL表达式-值栈的生命周期、及其原理(如何替代作用域)

    (1)值栈的生命周期
    生命周期: 一次请求过程.
     
    (2)#值栈如何替代作用域的(原理)
    原理:值栈的生命周期一次请求过程,但是值栈的context中的sessionMap中的数据可以跨请求存在,是因为其
    	  最终保存在HttpSession作用域中,HttpSession可跨多次请求。
    SessionMap底层源码实现:
    存入: 讲put方法接受的key和value,session.setAttribute(key,value);保存在session作用域中,。
    取出: 讲get方法接受key,session.getAttribute(key);,从session作用域中获的值
    

    9).拦截器(Interceptor)、拦截器栈(组)

    (1)拦截器
    概念: 拦截浏览器请求struts2的Action.
    作用(应用): 提取多个Action中的共同代码(通用功能),到拦截器中完成。
    运行机制:
       ①请求访问Action,会先经过拦截器中代码。
       ②请求经过拦截调用方法: intercept(ActionInvocation ai)
           ai.invoke();//放行action的请求。
    拦截器核心工作机制:(类比Filter)
     编码实现拦截器:
    ①自定义一个类,实现Interceptor接口
    public class MyInterceptor implements Interceptor{
    	//请求到达拦截器的执行方法。(类似filter中doFilter)
    	intercept(ai){
    	    Action之前运行的代码
    		ai.invoke();//放行请求。
    		Action运行之后的代码
    	}
    }
    ②注册配置拦截器(拦截器被struts2管理)
    <interceptors>
       <intercept name="名字" class=""></intercept>
    </interceptors>
    ③在需要拦截的action中引用拦截器(名字)
     
    ④拦截器修改跳转路径:
     
    ⑤拦截器和Action+跳转的完整流程。
     
    (2)拦截器栈(组)
     
    拦截器注意事项:
    如果aciton引用自定义拦截器的话,默认拦截器就失效了。
    struts-default[笔试]
    struts.xml中, `extends="struts-default"`
    默认拦截器中配置大量struts核心拦截器,(请求参数自动接收,文件上传,值栈,编码设置),如果action要使用这些拦截器,必须继承struts-default配置文件的额信息。而且还要引入Struts默认的拦截器,放到自己定义的拦截器栈的首个位置:
    

    10).Struts应用-文件的上传、下载

    (1)文件上传
    步骤:
    ①浏览器页面(文件选择输入框
       a. 文件输入框
       b. 表单提交方式 post
       c. 设置表单以二进制流提交: form enctyp="multipart/form-data"
    ②Action接受文件
       public class FileAction{
          	private File 文件输入框的name;
           	//set get;
       }
    ③在action讲接受file对象拷贝保存在tomcat项目所在的目录下
        //动态获得服务器中项目下的文件夹路径
       	ServletContext ctx = ServletActionContext.getServletContext();
       	String realPath = ctx.getRealPath("/upload");//upload文件夹的真实路径
       	String fileName = "hehe.jpg";
       	String filePath = realPath+"/"+fileName;
       	
       	//headPic文件----->filePath路径
       	OutputStream os = new FileOutputStream(filePath);
       	BufferedOutputStream bos = new BufferedOutputStream(os);
       	BufferedInputStream bis = new BufferedInputStream(new FileInputStream(headPic));
       	byte[] bs = new byte[1024];
       	while(true){
       		int i = bis.read(bs);//读入bs数组多少长度
       		if(i<0)break;
       		bos.write(bs, 0, i);
       	}
       	bos.flush();
       	bos.close();
       	bis.close();
    ④获得上传文件名:
     
    文件上传优化
    ①文件大小
        默认struts接受上传文件大小上限: 2M;
    	<!-- 常量配置设置文件上传的大小 -->
    	<!-- struts.multipart.maxSize=2097152   100M  1字节*100000000 -->
    	<constant name="struts.multipart.maxSize" value="100000000"></constant>
    ②文件名
        问题: 文件名在服务器端冲突。
        解决: 使用UUID生成唯一的名字作为文件名。
        代码: UUID.randomUUID().toString();"1234-1234-asdfg-2345-435"
        文件名设计: UUID+".后缀";
    ③保存路径
        问题: 保存文件的目录写死在代码中,耦合,不便于维护。
    解决办法: 保存目录名转移到配置文件。
     
    ④ io工具类:commons-io的jar包
    文件拷贝代码简化:FileUtils.copyFile();
    (2)文件下载
    使浏览器保存该文件,而不是解析展示该文件?
    给浏览器设置头信息: "content-disposition" "attachment;filename=文件.后缀"
    ①设置下载;
        response.setHeader("content-disposition", "attachment;filename="+fileName);
    ②读入服务器端文件输入流
    ③指向浏览器的输入流
    ④边读边写
    补充:
    	对下载的文件名编码:
        URLEncoder.encode(字符串,"UTF-8");
    

    11).Struts应用-验证码、令牌、日期转化(String/util.Date/sql.Date)

    (1)验证码
    作用:
    ①防止机器人登陆,对系统添加无效信息
    ②防止机器人,恶意注册无效用户信息
    使用java生成验证码图片:
    ①产生一个随机验证码字符串
    ②如何将字符串生成图片中
    public static BufferedImage getSafeCodeImage(String code) throws IOException {
        BufferedImage bi = new BufferedImage(80, 30, BufferedImage.TYPE_INT_BGR);
        Graphics g = bi.getGraphics();
        g.fillRect(0, 0, 80, 30);
        g.setColor(Color.BLUE);
        g.drawString(code, 20, 12);
        /*ImageIO.write(bi, "jpg", new FileOutputStream("D:\a.jpg"));*/
        return bi;
    }
    
    public static String getGenerateCode(int n) {
        String str = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
        Random rd = new Random();
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < n; i++) {
            sb.append(str.charAt(rd.nextInt(62)));
        }
        return sb.toString();
    }
    
    在jsp中产生一个验证码:
    验证码工具类:
    Hutool(工具包)
    导入hutool的jar包。
     CaptchaUtil   	功能: 生成随机验证码(字符串)、 生成验证码图片,直接通过流写出
    代码步骤:
    ①生成验证码对象: 
    			Captcha captcha = CaptchaUtil.createLineCaptcha(宽度,高度,字符个数,干扰线个数);
    			Captcha captcha = CaptchaUtil.createLineCaptcha(宽度,高度);
    ②生成验证码:
    			captcha.getCode();//code字符串
    			captcha.write(outputStream);//将验证码图片通过输出流,写出到对应位置
    
    jsp使用验证码核心思路:依靠image的src,请求生成验证码图片的action,响应写回去
     
    使用:
     
    (2)Struts2令牌机制
    防止表单重复提交
    ①分发令牌
    Struts中给用户分发令牌方式:	<s:token></s:token>
    作用: 
    a. 给用户的浏览器的表单放入一个随机字符串。
    b. 将字符串(令牌),向session中存入一份。
    核心机制:
     
    
    ②验证令牌
    验证令牌核心机制
     
    
    编码步骤:
    a. 书写一个验证令牌的拦截器(struts已经提供了) 
    b. 配置令牌拦截器拦截防止重复提交的action
    c. Action必须继承ActionSupport.
     
    
    (3)日期格式
    	①java.util.Date和java.sql.Date之间的转换:
    中间值:Date.getTime();
    例:
    long l = (new java.util.Date()).getTime();
    java.sql.Date d = new java.sql.Date(l);
    	②String格式转换为日期格式
    	日期格式化工具: SimpleDateFormat
    	String s = "1999-9-9";
    	//1. 创建日期格式化工具,(匹配日期格式)
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	//2. 调用转发方法
    	Date parse = format.parse(s);
    
  • 相关阅读:
    前台组件
    IntelliJ IDEA 简体中文专题教程
    干货分享 | 创业公司绝对不会告诉你他们在用的工具们
    线程的基本概念 / 计算机程序的思维逻辑
    Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    【转载】 准人工智能分享Deep Mind报告 ——AI“元强化学习”
    (待续)【转载】 DeepMind发Nature子刊:通过元强化学习重新理解多巴胺
    【转载】 机器学习算法岗的常见面试问题及准备
    【转载】 180623 Conda install 本地压缩包文件tar.bz2
    2017年 某次 实验室会议 —— 记
  • 原文地址:https://www.cnblogs.com/jwnming/p/13634991.html
Copyright © 2011-2022 走看看