A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Ljp 初级黑马   /  2018-3-15 19:00  /  658 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1、struts2在web.xml配置的Filter叫什么?
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        负责初始化整个Struts框架并且处理所有的请求
Struts2.1以前调用FilterDispatcher

2、struts2的Action有几种编写方式?
        第一种 创建类,这个类不继承任何类,不实现任何的接口
        第二种 创建类,实现接口 Action接口
        第三种 创建类,继承类 ActionSupport类,ActionSupport类是Action接口的实现类

3、能否在struts2的Action定义多个业务方法?如何做到不同的请求访问Action的不同方法?
        1method=...
        2使用通配符方式进行操作 ,使用符号 * 星号代表任意内容
        3访问Action中指定方法,不进行配置
           1) 在工程中使用 动态方法调用 ,必须保证 struts.enable.DynamicMethodInvocation = true 常量值 为true
           2) 在action的访问路径 中 使用 "!方法名"

4、xml进行struts2请求参数校验时,指定方法的校验和所有方法校验文件命名规则是什么?
        对指定的方法校验
                1针对动作类中的指定方法进行校验,使用@SkipValidation注解
                2格式  Action类名-ActionName(<action>元素name属性)-validation.xml
                        例如 : 校验AddCustomerAction中execute方法  配置 <action name="addcustomer" .../>
                        校验文件名字:
                        AddCusotmerAction-addcustomer-validation.xml
        所有方法校验
                在Action所在包 编写 Action类名-validation.xml 对Action所有业务方法进行校验

5、struts2的Action中如何使用ServletAPI?
        1、 在Action 中解耦合方式 间接访问 Servlet API  --------- 使用 ActionContext 对象
                actionContext = ActionContext.getContext();
                1) actionContext.getParameters(); 获得所有请求参数Map集合
                2) actionContext.put("company", "传智播客"); / actionContext.get("company") 对request范围存取数据
                3) actionContext.getSession(); 获得session数据Map,对Session范围存取数据
                4) actionContext.getApplication(); 获得ServletContext数据Map,对应用访问存取数据
        2、 使用接口注入的方式,操作Servlet API (耦合)
                ServletContextAware : 注入ServletContext对象
                ServletRequestAware :注入 request对象
                ServletResponseAware : 注入response对象
        3、 在Action中直接通过 ServletActionContext 获得Servlet API
                ServletActionContext.getRequest() : 获得request对象 (session)
                ServletActionContext.getResponse() : 获得response 对象
                ServletActionContext.getServletContext() : 获得ServletContext对象

6、struts2中有哪些常用结果类型?
        1) dispatcher :Action 转发给 JSP
        2)  chain :Action转发到另一个Action (同一次请求)
        3) redirect : Action重定向到 JSP
        4) redirectAction :Action重定向到另一个Action
        stream:下载用的(文件上传和下载时再议)
        plainText:以纯文本的形式展现内容
       
7、struts2中修改常量的方式?
        1) struts2 默认常量 在 default.properties 中配置
        2) 开发者自定义常量
                struts.xml (要求)
                                格式 : <constant name="struts.devMode" value="true" />
                struts.properties (要求)
                                格式 : struts.devMode = true
                web.xml
                                格式 :
                                <filter>
                                        <filter-name>struts2</filter-name>
                                        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
                                        <init-param>
                                                <param-name>struts.devMode</param-name>
                                                <param-value>true</param-value>
                                        </init-param>
                                </filter>

               
               
8、struts2中全局国际化的配置方式?
        创建一系列的资源文件 ,命名规范 :基本名称_小写语言_大写的国家.properties
                messages_zh_CN.properties
                messages_en_US.properties
        配置全局国际化
                使用struts.xml里面常量进行配置
                        常量名称:struts.custom.i18n.resources
                        常量的值:资源文件的基本名称
                        如果资源文件在src下面,直接写基本名称
                        如果资源文件在包下面,添加包路径  比如  cn/itcast/messages

9、addFieldError、addActionError 有何区别?
                都是com.opensymphony.xwork2.ActionSupport类下的方法.
        addActionError (String  anErrorMessage)
                添加一个Action级别的错误消息到Action
                        anErrorMessage: 错误消息,被存放在List列表中
                显示消息的标签是(如放在jsp页面中):
                        <s:actionerror />  显示全部的 Action级别的错误消息,可以加CSS代码
               
        addFieldError (String  fieldName, String  errorMessage)
                给一个字段(属性) 添加错误消息
                        fieldName: 字段(属性)名
                        errorMessage: 错误消息,被存放在一个Map<key, value>中(其中key存放的是fieldName,value存放的是errorMessage)。
                显示消息的标签是(如放在jsp页面中):
                        <s:fielderror />   显示全部的错误消息(用addFieldError方法添加的 )
               
        ActionSupport类还有一个 public boolean hasErrors () 方法,  其实他内部实现是这样的:
                (hasActionErrors() || hasFieldErrors())  , 分别检查有无Action级别的错误信息, 有无Fidld级别的错误的信息.
                只要一个为真, 就跳回input 实图, 并显示错误信息(如果你写了相应的标签)
               
               
10、简述struts2中自定义拦截器实现步骤?
        第一步 创建类 ,继承AbstractInterceptor类或继承MethodFilterInteceptor类
        第二步 重写AbstractInterceptor类里面 intercept方法,在这个方法中写逻辑
                        最后执行下一个操作return invocation.invoke();
        第三步 注册拦截器
                        在要拦截的action所在的package里面声明拦截器
                        在要拦截的action里面使用拦截器
                        如果使用自定义的拦截器,默认的拦截器不会执行的,手动使用默认的拦截器
                        <package name="demo2" namespace="/" extends="struts-default">
                                <interceptors>
                                        <interceptor name="pre" class="cn.itcast.demo2.Invacaton"></interceptor>
                                </interceptors>
                                <action name="demo2" class="cn.itcast.demo2.DemoAction" >
                                        <result>/index.jsp</result>       
                                        <result name="login">/demo100.jsp</result>
                                        <interceptor-ref name="pre"></interceptor-ref>
                                        <interceptor-ref name="defaultStack"></interceptor-ref>
                                </action>
                        </package>
                       
11、简述struts2 的拦截器执行原理?
        1.struts2中的拦截器的实现原理是AOP思想.
        2.struts2中的拦截器采用的是责任链模式
       
        当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,
        由这个代理对象调用Action的execute()或指定的方法前,
        在struts.xml中查找与该Action对应的拦截器。
        如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;
        如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
    如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。
       
        一个有序链表,通过递归调用,变成了一个堆栈执行过程,
        将一段有序执行的代码变成了2段执行顺序完全相反的代码过程,
        从而巧妙地实现了AOP。这也就成为了Struts2的Action层的AOP基础
       
        2个非常重要的推论:
                1. 如果在拦截器中,我们不使用invocation.invoke()来完成堆栈中下一个元素的调用,
                而是直接返回一个字符串作为执行结果,那么整个执行将被中止。
                2. 我们可以以invocation.invoke()为界,将拦截器中的代码分成2个部分,
                在invocation.invoke()之前的代码,将会在Action之前被依次执行,
                而在invocation.invoke()之后的代码,将会在Action之后被逆序执行。
                由此,我们就可以通过invocation.invoke()作为Action代码真正的拦截点,从而实现AOP

12、使用struts2如何实现多文件上传?
        1第一步 上传表单页面,满足三个要求,提交到action里面,要求:多个文件上传项name属性值必须要一样
        2创建action,在action实现多文件的上传,在action中使用数组形式得到多个文件的信息
                private File[] uploadImages;//得到上传的文件
                private String[] uploadImagesContentType;//得到文件的类型
                private String[] uploadImagesFileName;//得到文件的名称
        3遍历数组,得到每一个文件的信息,一个一个上传到服务器中
                if(uploadImages!=null&&uploadImages.length>0){
           for(int i=0;i<uploadImages.length;i++){
                File destFile = new File(realpath,uploadImageFileNames[i]);
                FileUtils.copyFile(uploadImages[i], destFile);
           }
        }
               
               
13、什么是值栈?
        贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象).
        相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象
       
        ValueStack 是 struts2 提供一个接口,实现类 OgnlValueStack ---- 值栈对象 (OGNL是从值栈中获取数据的 )
        每个Action实例都有一个ValueStack对象 (一个请求 对应 一个ValueStack对象 )
        在其中保存当前Action 对象和其他相关对象 (值栈中 是有Action 引用的 )
        Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中,request中 (值栈对象 是 request一个属性)

14、值栈的内部结构?
         值栈由两部分组成
                root            :compoundRoot其实就是一个ArrayList.
                context        :OgnlContext其实就是一个Map.context中有root的引用,request/session/application/parameters/attr对象引用.
                ValueStack中 存在root属性 (CompoundRoot) 、 context 属性 (OgnlContext )
                        * CompoundRoot 就是ArrayList
                        * OgnlContext 就是 Map
                context 对应Map 引入 root对象
                        * context中还存在 request、 session、application、 attr、 parameters 对象引用
                        * OGNL表达式,访问root中数据时 不需要 #, 访问 request、 session、application、 attr、 parameters 对象数据 必须写 #
                        * 操作值栈 默认指 操作 root 元素
                       
15、值栈ValueStack 和 ActionContext关系? 
        每一个Action都有一个属于自己的ValueStack对象.ActionContext是Action的上下文.从ActionContext中获取到ValueStack值栈对象.
        值栈对象是请求时创建的
        doFilter中 prepare.createActionContext(request, response);
                * 创建ActionContext 对象过程中,创建 值栈对象ValueStack
                * ActionContext对象 对 ValueStack对象 有引用的 (在程序中 通过 ActionContext 获得 值栈对象 )
        Dispatcher类 serviceAction 方法中 将值栈对象保存到 request范围
                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
       
16、如何获得值栈对象?
        获得值栈对象 有两种方法
        ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
        ValueStack valueStack2 = ActionContext.getContext().getValueStack();
       
17、向值栈保存数据?
        1// 将数据保存root的索引0位置,放置到第一个元素 ArrayList add(0,element);
                valueStack.push("itcast");
        2// 在值栈创建参数map, 将数据保存到map中
                valueStack.set("company", "传智播客");
          在jsp中 通过 <s:debug /> 查看值栈的内容
        3Action这个类默认就在栈中!!!如果Action有一个属性必然会在值栈中.
        操作的时候只需要在Action中提供一个属性.并且对这个属性提供get方法就可以在页面中获得。
       
18、在jsp中获取值栈内容?
        访问root中数据 不需要#
    访问 其它对象数据 加 #
        通过下标获取root中对象
   <s:property value="[0].top"/> //取值栈顶对象
        直接在root中查找对象属性 (自上而下自动查找)
        valueStack:<s:property value="username"/>
        (1)对象保存到值栈
        <s:property value="user.username"/>
        (2)  集合保存到值栈
        <s:property value="list[0].username"/>
        在OgnlContext中获取数据
        request:<s:property value="#request.username"/>
        session:<s:property value="#session.username"/>
        application:<s:property value="#application.username"/>
        attr:<s:property value="#attr.username"/>
        parameters:<s:property value="#parameters.cid"/>

19、EL为什么能访问值栈中的数据?
        StrutsPreparedAndExecuteFilter的doFilter代码中
request = prepare.wrapRequest(request);        
        * 对Request对象进行了包装 ,StrutsRequestWrapper
        * 重写request的 getAttribute
                Object attribute = super.getAttribute(s);
                if (attribute == null) {
                   attribute = stack.findValue(s);
                }
      访问request范围的数据时,如果数据找不到,去值栈中找
        request对象 具备访问值栈数据的能力 (查找root的数据)

Struts2中也可以使用EL表达式,但有些变化

从request范围中找不到那个属性,EL表达式就变成了OGNL表达式。其他EL功能都不变。

结论:
原来EL:${p}  page----->request----->session---->application
Struts2EL:${p}  page------>request----->根栈中的属性getP()--->从contextMap中找---->session---->application

20、过滤器和拦截器的区别
过滤器:在目标资源之前进行的操作
过滤所有的内容,比如action、servlet、jsp、html

拦截器:在目标资源之前进行的操作
不能拦截所有的内容,拦截action,不能拦截jsp,不能拦截html

拦截器和过滤器之间有很多相同之处,但是两者之间存在根本的差别。其主要区别为以下几点:
1)拦截器是基于JAVA反射机制的,而过滤器是基于函数回调的。
2)拦截器依赖于Servlet容器,而过滤器依赖于Servlet容器
3)拦截器只能对Action请求起作用,而过滤器可以对几乎所有的请求起作用。
4)拦截器可以访问Action上下文、值栈里的对象,而过滤器不能
5)在Action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马