面试题:struts 值栈 有用

一、 核心部分

1. 【核心试题】完成当天课堂练习

2. 【多选题】 阅读如下代码中,下列哪种方式可以在页面正确迭代获取集合中的数据 (ABC)

public String add(){

   ValueStack vs = ActionContext.getContext().getValueStack();

  // 压入List集合

  List<User> ulist = new ArrayList<User>();

   ulist.add(new User("小明",20));

   ulist.add(new User("小红",30));

    ulist.add(new User("小张",40));

   vs.set("ulist", ulist);

     return SUCCESS;

 }

public class User {

private String name;

 private Integer age;

 public User() {

 }

 public User(String name, Integer age) {

  this.name = name;

  this.age = age;

 }......

}

A <c:forEach items="${ ulist }" var="user"> ${ user.name } -- ${ user.age } </c:forEach>

B <s:iterator value="ulist"> <s:property value="name"/> <s:property value="age"/> </s:iterator>

C <s:iterator value="ulist" var="u"> <s:property value="#u.name"/> <s:property value="#u.age"/> </s:iterator>

D <s:iterator value="ulist"> <s:property value="#ulist.name"/> <s:property value="#ulist.age"/> </s:iterator>

3. 【多选题】 ValueStack结构是由哪两部分组成的 (AD)

 A CompoundRoot

 B Arraylist

 C Map

 D OgnlContext

4. 【多选题】 下列有关值栈组成部分的表述中错误的是 (CD)

A、 通常情况下,值栈由两部分组成root和context,默认情况下Struts会把 动作和相关对象压入 ObjectStack中,会把各种各样的映射关系压入 Context 中。

B、 在ValueStack中存在root属性、context 属性,其中root属性代指的就是ArrayList, context属性代指的就是Map

 C、 OGNL表达式访问值栈中的数据必须使用#才能实现访问。

 D、 当我们操作值栈内容时,默认操作的就是map中的元素。

5. 【多选题】 下列有关ValueStack ActionContext对象的相关理解中正确的是 (ABCD)

  A、 ActionContext是绑定到当前的线程上,那么在每个拦截器或者Action中获取到的ActionContext是同一个。

 B、 值栈对象是当请求时才会被创建的

 C ActionContext中存在一个Map集合,该Map集合和ValueStack的context是同一个地址。

D、 ActionContext中可以获取到ValueStack的引用,我们可以使用ActionContext来获取到值栈对象。

6. 【多选题】 下列选项中有关OGNL(对象图导航语言)的表述正确的是 (AB)

A、 当我们以任意的一个对象为根,我们通过OGNL可以访问与这个对象关联的其它对象。

B、 通过ognl简单一致的表达式语法,我们可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。

  C、 表现层框架都默认使用OGNL作为表达式语言。

 D、 OGNL通常支持对象方法调用、类静态的方法调用和值访问,但是不支持集合对象的相关操作。

 

7. 【多选题】 当我们向值栈的root属性中保存数据时,如下哪些方式是正确的 (AC)

   A、 valueStack.push(Object obj);

  B、 valueStack.push(String key, Object obj);

  C、 valueStack.set(String key, Object obj);

  D、 valueStack.set(Object obj);

8. 【多选题】 下列选项中有关值栈的相关概念表述正确的是 (ABD)

A、 值栈就相当于一个数据的中转站,我们可以向值栈存入一些数据,同样也可以从值栈中获取到数据。

B、 ValueStack是struts2框架提供一个接口,具体的实现类是ognlValueStack。

C、 默认情况下struts2框架下Action是单例的,当请求一访问,就会创建一个Action实例,同时也会创建一个ActionContext对象,代表的是Action的上下文对象,最后还会创建一个ValueStack对象。

  D、 通常情况下每一个Action实例都有一个ValueStack对象。

9. 【编程题】在jsp页面使用迭代标签迭代集合值

需求:写一个Action,初始化List集合数据,存储在值栈的root(根元素)对象中,再在jsp页面使用迭代标签迭代集合值。

操作步骤

  1. 新建action,继承ActionSupport
  2. 新建对象:User.java
  3. action的成员变量中定义list(集合的元素为User对象)
  4. 重写execute()方法, 给集合对象赋值
  5. jsp页面,迭代显示集合值

 

Action代码:

 

public class TagTestAction extends ActionSupport{

 

// 数据存储到根元素中!

private List<User> list;

public List<User> getList() {

return list;

}

 

 

@Override

public String execute() throws Exception {

 

list = new ArrayList<User>();

 

// 初始化

for (int i=1; i<6; i++) {

User user = new User("Kobe"+i,"999");

list.add(user);

}

 

return super.execute();

}

 

}

 

 

注:答案在答案\编程题9

二、 晋级部分

需求:使用struts的<s:property>标签,结合OGNL表达式获取值栈中Map数据,也是ValueStack值栈对象中context中数据。

需求详述:

通过ActionContext获取表示request、session、application域的map, 再往map中设置值,最后再在jsp页面通过struts2的标签获取值 (<s:property>)

操作步骤

(1)  新建action类

(2)  action类的方法中,通过ActionContext 获取表示request、session applicatoin域对象的map集合,再设置map值。

(3)  配置struts.xml

(4)  通过jsp页面获取map集合值

 

注:答案在答案\晋级题1

 

三、 面试题部分

1. 值栈对象的创建 ValueStack ActionContext 是什么关系

答案:

值栈对象是请求时创建的 

doFilter中 prepare.createActionContext(request, response); 

    * 创建ActionContext对象过程中,创建值栈对象ValueStack 

    * ActionContext对象对ValueStack对象有引用的(在程序中通过 ActionContext 获得值栈对象 ) 

Dispatcher类 serviceAction 方法中将值栈对象保存到request范围

    request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

2. 如何获得值栈对象?

答案:

1、ActionContext.getContext().get(ActionContext.VALUE_STACK);                        2、ActionContext.getContext().getValueStack();                                                              3、ServletActionContext.getRequest().getAttribute("struts.valueStack");   

 

3. 什么是值栈?值栈的内部结构?

答案:

 ValueStack 是 struts2 提供一个接口,实现类 OgnlValueStack ---- 值栈对象 (OGNL是从值栈中获取数据的 )每个Action实例都有一个ValueStack对象 (一个请求对应 一个ValueStack对象 )在其中保存当前Action 对象和其他相关对象 (值栈中是有Action引用的 )Struts 框架把 ValueStack 对象保存在名为“struts.valueStack” 的请求属性中,request中(值栈对象是request一个属性)

值栈由两部分组成,ObjectStack(root)ContextMap(context)

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

VaValueStack中 存在root属性 (CompoundRoot) 、 context 属性 OgnlContext )

    * CompoundRoot 就是ArrayList

    * OgnlContext 就是 Map

cncontext 对应Map 引入 root对象 

    * context中还存在 request、 session、application、 attr、 parameters 对象引用 

    * OGNL表达式,访问root中数据时 不需要 #, 访问 request、 session、application、 attr、 parameters 对象数据 必须写 # 

    * 操作值栈 默认指 操作 root 元素

 

 

 

 

 

 

  1. 什么是OGNL表达式.

OGNL的全称是对象图导航语言, 可以通过某种表达式语法,存取Java对象的任意属性调用Java对象的方法同时能够自动实现必要的类型转换.

  1. OGNL表达式的使用要求是什么

要想使用ognl表达式,一般情况下都得需要使用struts2的标签库。

  1. 怎样用s标签把value属性取值所对应的内容输出到浏览器。

<s:property value=""/>

  1. 阐述一下 s:property的作用。

value属性取值所对应的内容输出到浏览器上。注意:它不是把value的值输出到浏览器上

  1. 用<s:property/>写一段代码把一个 ”OGNL表达式” 看成是字符串

<s:property value="%{'OGNL表达式}"/> 

<s:property value='%{"OGNL表达式"}'/>

简化的表现形式:'OGNL表达式'或者是"OGNL表达式",单引号还是双引号由外层决定。

  1. 用<s:property/>写一段代码,怎样把一个字符串”OGNL表达式看成OGNL表达式?

把一个字符串看成是OGNL表达式的方式是: %{字符串}

<s:property value='%{OGNL表达式}'/>

 

  1. OGNL表达式可以访问普通的方法,写一段代码用<s:property>标签完成下面的需求:
    1. 计算字符串”OGNLExpression”的长度 ,并输出
    2. 字符串”OGNLExpression”转成大写,并输出
    3. 用字符’e’分割字符串”OGNLExpression”,并输出

代码如下:

<s:property value='"OGNLExpression".length()'/><br/>

<s:property value='"OGNLExpression".toUpperCase()'/><br/>

<s:property value='"OGNLExpression".split("E")'/><br/>

 

  1. OGNL表达式可以访问静态属性,访问静态属性,必须按照规则写:@包名.包名....类名@静态属性名称,请用<s:property> 输出Integer的最大值。

<s:property value="@java.lang.Integer@MAX_VALUE"/>

 

  1. OGNL表达式可以访问静态方法,访问静态方法必须按照规则写:@包名.包名....类名@静态方法名称,struts2默认不允许OGNL访问静态方法,要想使用需要配置文件中开启,请在jsp中用<s:property>输出Math类调用random()方法产生的随机数。

struts2框架默认不支持OGNL表达式的静态方法调用,开启的方式如下:

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

--%>

随机数:<s:property value="@java.lang.Math@random()"/>

 

 

 

  1. HTML标签在浏览器输出一套性别的单选按钮:

<input type="radio" name="gender" value="">

<input type="radio" name="gender" value="">

<br/>

Struts2标签也有一个radio,也是用于在浏览器上输出一套性别单选按钮,list属性的取值是一个OGNL表达式,可以使用{}来创建一个List集合,请用在页面写出代码?

<s:radio name="gender" list="{'',''}" label="性别"/>

 

 

  1. HTML在浏览器上输出一个单选性别:

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

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

<br/>

Struts2标签的radiolist属性的取值是一个OGNL表达式,可以使用#{key:value,key:value}来创建一个Map集合,请用代码完成。

<s:radio name="gender" list="#{'male':'','female':''}" label="性别"/>

 

 

  1. 请简述一下ContextMap,并画出ContextMap的结构图

ContextMap是ognl上下文对象,结构map<String,Object>封装了一次请求的所有数据。

结构图如下:

 

 

  1. 用自己的话请阐述ActionContext对象。

是一个工具类,是struts2框架提供给我们的,可以让我们调用其中的方法,快速的操作ContextMap。用它操作OGNL上下文对象

 

  1. ActionContext对象以及和ContextMap(context)的关系

ActionContext就相当于对ContextMap进行了一次再封装。

 

  1. 框架是怎么保证ActionContext的线程安全的?

javaweb工程是多线程的,那么每个线程在访问Action时,都会创建自己的ActionContext,每次创建ActionContext时,把对象绑定到当前线程上。

  1. 怎样获取一个ActionContext对象?

获取ActionContext对象:ActionContext context = ActionContext.getContext();

 

  1. 请按下面的需求完成对ActionContext设置值和取值的练习。

1.获取ActionContext对象,并且存入数据key是字符串 "contextMap", value是字符串 "hello context map ",在jsp页面用<s:property value="#contextMap"/>取值并显示。

2. 获取ActionContext对象,然后获取keyapplicationMap,并且存入数据key是字符串 " applicationMap ", value是字符串 " hello application map ",在jsp页面用<s:property value="#application.applicationMap"/>取值并显示。

3. 获取ActionContext对象,然后获取keysessionMap,并且存入数据key是字符串 "sessionMap", value是字符串 "hello session map",在jsp页面用<s:property value="#session.sessionMap"/>取值并显示。

  1. 请阐述一下ValueStack对象

ValueStackStruts的一个接口,字面意义为值栈,OgnlValueStack是ValueStack的实现类,客户端发起一个请求struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,OgnlValueStack贯穿整个 Action 的生命周期。

它是ContextMap中的一部分,里面的结构是一个List,是我们可以快速访问数据一个容器。它的封装是由struts2框架完成的。

通常情况下我们是从页面上获取数据。

 

  1. 请阐述一下ValueStack的内部结构

OnglValueStack 中包含了一个CompoundRoot的对象,该对象继承了ArrayList,并且提供了只能操作集合第一个元素的方法,所以我们说它实现了栈的特性。同时,它里面定义了一个ContextMap的引用,也就是说,我们有值栈对象,也可以通过值栈来获取ContextMap

 

  1. 根据下面需求完成对ValueStack的操作练习。

1.获取ActionContext对象,然后获取ValueStack对象,然后创建一个User对象,User对象有nameage属性,压入栈中,然后通过<s:property value="name"/>获取里面name的值。

2.Demo2Action中定义一个成员变量name=”张三”,在页面中通过<s:property value="[1].name"/>获取值,并在页面显示。

  1. 如下图,完成下面需求

 

ContextMap 中放入一个name属性,在request域中放入一个name属性,session放入一个name属性,并且在Demo3Action中加一个name的成员变量,然后通过页面el表达式取name的值,然后总结一下el表达式的取值顺序。

1.先编写代码去实现,然后总结规律。

2.规律总结如下:

Struts2框架中对EL表达式做了如下改变:

EL表达式原来的搜素顺序:

page Scope——>request Scope——>sessionScope——>application Scope

EL表达式改变后的搜索顺序:

page Scope>request Scope>valueStack>contextMap>sessionScope

>application Scope

它是如何做到的呢?答案就是,struts2框架对request对象进行了包装,并且对getAttribute方法进行了增强

 

  1. #号,%号,$号做一下总结

#

1、获取ContextMap中数据,把后面的内容看成是key

2、在使用struts2标签,创建Map对象时使用。<s:radio list="#{}">

%

1、使用%{''}OGNL表达式强制看成是普通字符串

2、使用%{}把普通字符串强制看成是OGNL表达式

$:

1、使用EL表达式的标识

2、在struts的配置文件中使用OGNL表达式

 

 

  1. 编程题,优化struts2的查询客户案例,在CustomerAction中定义一个成员变量private List<Customer> customers,然后提供getset方法,然后页面集合遍历集合修改为<s:iterator value="customers" var="cust">和<s:iterator value="customers">

 

posted @ 2018-05-18 19:49  阿善9  阅读(363)  评论(0编辑  收藏  举报