Struts2--day04

非本人总结的笔记,抄点笔记复习复习。感谢传智博客和黑马程序猿


Struts2--day04_第1张图片
记笔记啊记笔记

Ognl的简介

Ognl是独立的项目,不是Struts2的一部分,只是经常和Struts2一起使用,获取值栈的数据。如果想要使用Ognl首先导入包。

El表达式,在jsp页面中获取域对象里面的数据,显示到页面中。

Ognl表达式比El表达式强大

  1. 支持对象方法调用,如xxx.xxx();
  2. 支持类静态方法调用和值访问,表达式的格式:@[类全名(包括包路径)]@[方法名|值名]。例如:@java.lang.String@format('foo%s', 'bar')或@tutorial.MyConstant@APP_NAME。设置 struts.ognl.allowStaticMethodAccess=true
  3. 访问OGNL上下文(OGNL content)和ActionContent;(操作值栈数据)
  4. 支持赋值操作和表达式串联
  5. 操作值栈集合对象

Ognl入门案例

使用ognl和Struts2标签一起做下面的操作

第一步 创建Ognl.jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib uri="/struts-tags" prefix="s"%>


      
    My JSP 'helloOgnl.jsp' starting page
  
  
    
        
    
<%--调用静态方法 格式:@[类全名(包括包路径)]@[方法名] --%>

第二步 配置struts.xml调用静态方法,必须开启常量值



值栈

什么是值栈

值栈是数据的中转战,类似于域对象,之前操作,可以向域对象里面设置值,可以从域对象里面获取值。向域对象设置值,从域对象获取值。获取值栈的数据,可以通过struts2标签和ognl表达式获取。

每次访问action的时候,都会创建action实例,每个action实例里面只有一个值栈对象(valueStack对象)

在action实例中,值栈是如何存在的?

Struts2框架将把ValueStack对象保存在名为"struts.valueStack",的请求属性中,request中Request.setAttribute("struts.valueStack")

获取值栈对象方法

第一种

从request域对象里面使用getAttribute获取,名称为struts.valueStack

第二种

得到ActionContext,使用ActionContext里面的方法得到

案例演示

第一步 创建Action

package cn.itcast.valuestack;

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;
/**
 * 获取值栈对象的两种方式
 */
public class StackDemo1 extends ActionSupport {

    private String name;
    
    @Override
    public String execute() throws Exception {
        //第一种 从request域对象里面使用getAttribute获取,名称struts.valueStack
        //第一种方式  从request域里面获取
        HttpServletRequest request = ServletActionContext.getRequest();
        ValueStack stack1 = (ValueStack) request.getAttribute("struts.valueStack");
        //第二种 得到ActionContext,使用ActionContext里面的方法得到
        //第二种方式 使用ActionContext获取
        ActionContext context = ActionContext.getContext();
        ValueStack stack2 = context.getValueStack();
        //每个action实例中只有一个值栈对象
        //值是 true,表示是一个对象
        System.out.println(stack1 == stack2);
        return SUCCESS;
    }
}

第二步 配置Action struts.xml


     
          /index.jsp
     

值栈的内部结构

值栈包含两部分内容

  1. Root:是list集合,Struts2里面默认操作数据都在root里面
  2. Context:是map集合

在action里面把数据放到域对象里面,这个数据存到context里面,context里面的Map结构,key名称为request、session、Application、attr、parameters

Struts2--day04_第2张图片
值栈

向值栈中存放数据

第一种 获取值栈对象,调用值栈对象里面的方法的set方法

第二种 获取值栈对象,调用值栈对象的方法push方法

第三种 在action中创建对象,生成set和get方法

案例演示

第一步 创建Action

package cn.itcast.valuestack;

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;
/**
 * 向值栈放数据的方式
 */
public class StackDemo2 extends ActionSupport {
    //第三种
    //创建对象
    private User user = new User();
    //生成对象的get和set方法
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String execute() throws Exception {
        //第一种 获取值栈对象,调用值栈对象里面的方法set方法
        //获取值栈对象
        ValueStack stack = ActionContext.getContext().getValueStack();
        //设置值
        stack.set("itcast", "东方不败");    
    
        //第二种 获取值栈对象,调用值栈对象的方法push方法
        stack.push("岳不群");  

        //第三种 在action中创建对象,生成get和set方法
        //演示效果: 向值栈中放对象,在页面中获取对象值   
        //栈特点:后进先出      
        //向值栈的user对象里面设置值
        user.setUsername("lucy");
        user.setPassword("250");
        
        return SUCCESS;
    }
}

第二步 配置struts.xml


    /stack/demo2.jsp

第三步 创建页面 demo.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'demo2.jsp' starting page
    
  
    
<%--

    
    
--%> <%-- -- --%> ${itcast }<%--EL表达式直接获取数据-->

第四步 创建User类

package cn.itcast.valuestack;

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;
    }
}

从值栈中获取值

第一种 获取值栈的root里面的值:对象和list集合

获取值栈的root的对象的值



获取值栈的root里面list集合内容

第一步 创建action
package cn.itcast.valuestack;

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

import com.opensymphony.xwork2.ActionSupport;
/**
 * 向值栈放数据的方式
 * @author asus
 *
 */
public class StackDemo3 extends ActionSupport {
    // 获取root的list集合的值
    //创建list集合
    private List list = new ArrayList();
    //生成list集合的get和set方法
    public List getList() {
        return list;
    }
    public void setList(List list) {
        this.list = list;
    }

    @Override
    public String execute() throws Exception {
        //向list集合中设置值
        //创建多个user对象,放到list集合
        User u1 = new User();
        u1.setUsername("岳不群");
        u1.setPassword("119");
        User u2 = new User();
        u2.setUsername("林平之");
        u2.setPassword("999");
        
        list.add(u1);
        list.add(u2);
        
        return SUCCESS;
    }
}
第二步 配合struts.xml

    /stack/demo3.jsp

第三步 创建jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    
    My JSP 'demo2.jsp' starting page

  
  
  

   
   
   --
   
   
--

第二种 获取值栈的context里面的值:对象和list集合

获取值栈的context里面的对象

第一步 创建action
package cn.itcast.valuestack;

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

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 *  向context里面放对象
 */
public class StackDemo4 extends ActionSupport {
    
    @Override
    public String execute() throws Exception {
        //创建对象
        User user = new User();
        user.setUsername("mary");
        user.setPassword("520");
        //把对象放到request域对象里面先得到在放到context中
        ServletActionContext.getRequest().setAttribute("userrequest", user);
        
        return SUCCESS;
    }
}
第二步 配置struts.xml

    /stack/demo4.jsp

第三步 创建jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'demo2.jsp' starting page
   
  
   
   
   --
   
  

获取值栈的context里面的list集合

第一步 创建action
package cn.itcast.valuestack;

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

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 向值栈放数据的方式
 */
public class StackDemo5 extends ActionSupport {
    @Override
    public String execute() throws Exception {
        //向context里面放list集合
        //创建对象
        User u1 = new User();
        u1.setUsername("岳不群");
        u1.setPassword("119");
        User u2 = new User();
        u2.setUsername("林平之");
        u2.setPassword("999");
        //创建list集合
        List list = new ArrayList();
        list.add(u1);
        list.add(u2);
        //放到域对象
        ServletActionContext.getRequest().setAttribute("userlist", list);
        
        return SUCCESS;
    }
}
第二步 配置struts.xml

    /stack/demo5.jsp

第三步 创建jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    
    My JSP 'demo2.jsp' starting page

  
  
  
   
   
   -- 
   
   
--

EL表达式为什么可以获取值栈数据

实现原理:首先增强request里面的getAttribute方法,而getAttribute方法获取域对象里面的值

增强逻辑:首先调用getAttribute获取域对象里面的值,如果获取了值,直接返回;如果获取不到域对象的值,获取到值栈对象,从值栈中把值取出来,赋值给域对象中的参数数据。所以,通过EL表达式就可以获取值栈数据。

Ognl中#的使用

用来获取值栈里面context里面的数据




Ognl表达式的%的使用

一般使用在Struts2的表单标签里面

演示效果:

  1. 编写action,向request里面设置值
  2. 到jsp中获取request域里面设置的值
  3. 在jsp中把值显示到Struts2表单中

第一步 创建Action

package cn.itcast.ognl;

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

import org.apache.struts2.ServletActionContext;

import cn.itcast.valuestack.User;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 编写action,向request域里面设置值
 */
public class OgnlDemo2 extends ActionSupport {
    
    @Override
    public String execute() throws Exception {
        //向request域里面设置值
        ServletActionContext.getRequest().
                    setAttribute("username", "requestValueOgnl");
        
        return SUCCESS;
    }
}

第二步 配置struts.xml


    /ognl/ognl2.jsp

第三步 创建jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


     
    My JSP 'ognl1.jsp' starting page
   
  

    用户名: 
  

Ognl表达式的$的使用

在国际化资源文件中使用

在properties文件中msg=欢迎您 ${#request.username}

在页面


    


Struts2座文件下载用


    attachment;file=${filename}
    ${inputstream}

总结值栈和ognl表达式

1、ognl

ognl不是Struts2表达式的一部分,是独立的项目,经常和Struts2的标签一起使用,获取值栈

2、值栈

类似域对象,数据的中转站,存值和取值

每个Action对象里面都只有一个值栈对象,在值栈request域里面

3、获取值栈对象有两种

  1. 从request域对象里面获取
  2. ActionContext类方法获取

4、放数据到值栈有三种

  1. set方法
  2. push方法
  3. 创建对象,生成get和set方法

5、从值栈去数据


获取context里面数据,ognl之前写#

6、El表达式获取值栈数据

7、 %和$的使用

8、值栈内部结构

Root是list集合;Context是Map集合;Struts2里面默认操作数据都在Root里面,把数据放到域对象里面存到context里面

Struts2的标签库

通用标签库











Struts2表单标签UI标签库

介绍

Html中表单标签

Form :属性 action、method、enctype

在form里面有很多的输入项

大部分在input里面 type=””

text : 普通输入项

password :密码输入项

radio :单选输入项

checkbox:复选框

file: 文件上传项

hidden:隐藏项

button:普通按钮

submit: 提交按钮

reset: 重置按钮

select : 下拉输入框

textarea:文本域

struts2的表单标签对应的输入项,没有文件上传输入项

struts2表单标签实现

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'struts2tag.jsp' starting page
    
  

    
    
    
  

Struts2的表单标签数据回显

现象: 只是校验其中的一个输入项是否为空,但是把其他的输入项也清空了

演示一:使用普通的html标签,提交表单数据到action,进行数据的校验

创建页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'tagCommon.jsp' starting page
    
  
      <%--真正的错误--%>
    
username:
password:
address:

创建Action

package cn.itcast.tag;

import com.opensymphony.xwork2.ActionSupport;

public class Tag1Action extends ActionSupport {
    //属性封装方法
    private String username;
    private String password;
    private String address;
    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 String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    
    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
        return SUCCESS;
    }
}

配置struts.xml


    /index.jsp
    /tag/tagstruts2.jsp

通过xml做配置校验 Tag1Action-validation.xml放到action的包下




    
        
            用户名不能为空xml
        
    

演示二:使用struts2的表单标签,提交数据到action,进行数据的校验

创建页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'tagCommon.jsp' starting page
   
     <%--action直接写action的名字就行 不要写绝对路径--%>
    
        
        <%--写上showPassword="true"密码才会回显--%>


        
        
    
  

创建Action

package cn.itcast.tag;

import com.opensymphony.xwork2.ActionSupport;

public class Tag1Action extends ActionSupport {
    //属性封装方法
    private String username;
    private String password;
    private String address;
    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 String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    
    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
        return SUCCESS;
    }
}

配置struts.xml


    /index.jsp
    /tag/tagstruts2.jsp

通过xml做配置校验 Tag1Action-validation.xml放到action的包下




    
        
            用户名不能为空xml
        
    

防止表单重复提交

防止表单重复提交原理:

使用令牌机制 javaweb原理

第一步 在表单里面做几件事情

(1)在表单页面中生成随机的唯一的值 uuid
 <%
           Stirng uuid =UUID.randomUUID().toString()
%>
(2)把生成的唯一的值首先放到页面的隐藏项里面 hidden
 
(3)还要把生成的唯一的值再放到session域里面
session.setAttribute("id",uuid);

第二步 提交表单到action,

(1) 获取隐藏项里面的uuid值

(2) 获取session域对象里面的uuid值

(3) 比较这两个值是否相同,如果相同,获取表单其他值进行操作

(4) 操作完成之后,把session域里面的值清空

(5) 如果这两个值,不相同,不进行操作

使用struts2防止表单重复提交

使用struts2里面拦截器实现,token,这个token拦截器不是默认执行的拦截器

创建页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%--引入struts标签--%>
<%@ taglib uri="/struts-tags" prefix="s"%>


  
    My JSP 'form1.jsp' starting page
    
  
   
<%--使用struts标签token--%>

创建Action

package cn.itcast.form;

import com.opensymphony.xwork2.ActionSupport;

public class FormSubmitAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println("ACTION执行了.............");
        return SUCCESS;
    }
}

使用token拦截器 配置action

token拦截器不是默认的所以要声明拦截器 struts.xml

----------------------配置位置在struts.xml中

        
            
<%--因为token不是默认的所以要声明默认的否则默认的会失效--%>
            
        




--------------------配置位置在struts.xml中

        
        /index.jsp
<%--使用token拦截器之后返回的视图不是input而是invalid.token--%>
        /form/form1.jsp

你可能感兴趣的:(Struts2--day04)