struts2面试题

来源:互联网 发布:底部反转形态 知乎 编辑:程序博客网 时间:2024/06/06 14:26

一、struts2工作流程
1、Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。
1)核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。
2)业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。
        Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。
2、基本简要流程如下:
1)客户端初始化一个指向Servlet容器的请求;
2)这个请求经过一系列的过滤器(Filter)
       (这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3)接着FilterDispatcher被调用,
         FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4)如果ActionMapper决定需要调用某个Action,
         FilterDispatcher把请求的处理交给ActionProxy
5)ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6)ActionProxy创建一个ActionInvocation的实例。
7)ActionInvocation实例使用命名模式来调用,
         在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8)一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。       在这个过程中需要涉及到ActionMapper
9)响应的返回是通过我们在web.xml中配置的过滤器
10)如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理sreadlocal ActionContext;如果ActionContextCleanUp不使用,则将会去清理sreadlocals。 
 

二、说下Struts的设计模式
MVC模式:
1、web应用程序启动时就会加载并初始化ActionServler。
2、用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法.
3、Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。

三、拦截器和过滤器的区别
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
 

四、struts1于struts2的比较
1、Action   类: 

    Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
  Struts   2   Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
2、线程模式: 
    Struts1   Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1   Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
Struts2   Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
3、Servlet   依赖: 
    Struts1   Action   依赖于Servlet   API   ,因为当一个Action被调用时HttpServletRequest   和   HttpServletResponse   被传递给execute方法。
Struts   2   Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2   Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest   和   HttpServletResponse的必要性。
4、可测性: 
   测试Struts1   Action的一个主要问题是execute方法暴露了servlet   API(这使得测试要依赖于容器)。一个第三方扩展--Struts   TestCase--提供了一套Struts1的模拟对象(来进行测试)。
Struts   2   Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
5、捕获输入: 
   Struts1   使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。
Struts   2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过   web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种   ModelDriven   特性简化了taglib对POJO输入对象的引用。
6、表达式语言: 
   Struts1   整合了JSTL,因此使用JSTL   EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言-- "Object   Graph   Notation   Language "   (OGNL).
7、绑定值到页面(view): 
   Struts   1使用标准JSP机制把对象绑定到页面中来访问。
   Struts   2   使用   "ValueStack "技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
8、类型转换: 
   Struts   1   ActionForm   属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
  Struts2   使用OGNL进行类型转换。提供基本和常用对象的转换器。
9、校验: 
   Struts   1支持在ActionForm的validate方法中手动校验,或者通过Commons   Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
   Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
10、Action执行的控制: 
   Struts1支持每一个模块有单独的Request   Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
   Struts2支持通过拦截器堆栈(Interceptor   Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。


五、为什么要使用Struts2
Struts2 是一个相当强大的Java Web开源框架,是一个基于POJO的Action的MVC Web框架。它基于当年的Webwork和XWork框架,继承其优点,同时做了相当的改进。
1、Struts2基于MVC架构,框架结构清晰,开发流程一目了然,开发人员可以很好的掌控开发的过程。
2、使用OGNL进行参数传递。
OGNL提供了在Struts2里访问各种作用域中的数据的简单方式,你可以方便的获取Request,Attribute,Application,Session,Parameters中的数据。大大简化了开发人员在获取这些数据时的代码量。
3、强大的拦截器
Struts2 的拦截器是一个Action级别的AOP,Struts2中的许多特性都是通过拦截器来实现的,例如异常处理,文件上传,验证等。拦截器是可配置与重用的,可以将一些通用的功能如:登录验证,权限验证等置于拦截器中以完成一些Java Web项目中比较通用的功能。在我实现的的一Web项目中,就是使用Struts2的拦截器来完成了系统中的权限验证功能。
4、易于测试
Struts2的Action都是简单的POJO,这样可以方便的对Struts2的Action编写测试用例,大大方便了5Java Web项目的测试。
易于扩展的插件机制在Struts2添加扩展是一件愉快而轻松的事情,只需要将所需要的Jar包放到WEB-INF/lib文件夹中,在struts.xml中作一些简单的设置就可以实现扩展。
6、模块化管理
Struts2已经把模块化作为了体系架构中的基本思想,可以通过三种方法来将应用程序模块化:将配置信息拆分成多个文件把自包含的应用模块创建为插件创建新的框架特性,即将与特定应用无关的新功能组织成插件,以添加到多个应用中去。
7、全局结果与声明式异常
为应用程序添加全局的Result,和在配置文件中对异常进行处理,这样当处理过程中出现指定异常时,可以跳转到特定页面。
他的如此之多的优点,是很多人比较的青睐,与spring ,Hibernate进行结合,组成了现在比较流行的ssh框架,当然每个公司都要自己的框架,也是ssh变异的产品。


六、struts2有哪些优点?
1、在软件设计上Struts2的应用可以不依赖于Servlet API和struts API。 Struts2的这种设计属于无侵入式设计; 
2、拦截器,实现如参数拦截注入等功能; 
3、类型转换器,可以把特殊的请求参数转换成需要的类型; 
4、多种表现层技术,如:JSP、freeMarker、Velocity等; 
5、Struts2的输入校验可以对指定某个方法进行校验; 
6、提供了全局范围、包范围和Action范围的国际化资源文件管理实现 
 

七、struts2是如何启动的?
 
1、struts2框架是通过Filter启动的,即StrutsPrepareAndExecuteFilter,此过滤器为struts2的核心过滤器; 
3、StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。struts2读取到struts.xml的内容后,是将内容封装进javabean对象然后存放在内存中,以后用户的每次请求处理将使用内存中的数据,而不是每次请求都读取struts.xml文件。
 

八、struts2框架的核心控制器是什么?它有什么作用? 
1、Struts2框架的核心控制器是StrutsPrepareAndExecuteFilter。 
2、作用: 
 负责拦截由<url-pattern>/*</url-pattern>指定的所有用户请求,当用户请求到达时,该Filter会过滤用户的请求。默认情况下,如果用户请求的路径 
不带后缀或者后缀以.action结尾,这时请求将被转入struts2框架处理,否则struts2框架将略过该请求的处理。 
可以通过常量"struts.action.extension"修改action的后缀,如: 
<constant name="struts.action.extension" value="do"/> 
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。
<constant name="struts.action.extension" value="do,go"/>   
 

九、struts2配置文件的加载顺序? 
struts.xml ——> struts.properties 
常量可以在struts.xml或struts.properties中配置,如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值. 
struts.xml文件的作用:通知Struts2框架加载对应的Action资源
 

十、struts2常量的修改方式? 
常量可以在struts.xml或struts.properties中配置,两种配置方式如下: 
1、在struts.xml文件中配置常量 
<constant name="struts.action.extension" value="do"/> 
2、在struts.properties中配置常量(struts.properties文件放置在src下): 
struts.action.extension=do
 
 
struts2如何访问HttpServletRequest、HttpSession、ServletContext三个域对象? 
方案一: 
HttpServletRequest request =ServletActionContext.getRequest(); 
HttpServletResponse response =ServletActionContext.getResponse(); 
HttpSession  session=   request.getSession();
ServletContext servletContext=ServletActionContext.getServletContext();  
   
方案二: 
类 implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware 
注意:框架自动传入对应的域对象 
 
 

十二、struts2是如何管理action的?这种管理方式有什么好处? 
struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的。 
主要用于管理一组业务功能相关的action。在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下。 
struts2中的默认包struts-default有什么作用? 
1、struts-default包是由struts内置的,它定义了struts2内部的众多拦截器和Result类型,而Struts2很多核心的功能都是通过这些内置的拦截器实现,如:从请求中 
把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了struts-default包才能使用struts2为我们提供的这些功能。  
2、struts-default包是在struts-default.xml中定义,struts-default.xml也是Struts2默认配置文件。 Struts2每次都会自动加载 struts-default.xml文件。 
3、通常每个包都应该继承struts-default包。      
 
 
 
十三、struts2如何对指定的方法进行验证? 
1)validate()方法会校验action中所有与execute方法签名相同的方法; 
2)要校验指定的方法通过重写validateXxx()方法实现, validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写; 
3)当某个数据校验失败时,调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport), 如果系统 的fieldErrors包含失败信息,struts2会将请求转发到名为input的result; 
4)在input视图中可以通过<s:fielderror/>显示失败信息。 
5)先执行validateXxxx()->validate()->如果出错了,会转发<result name="input"/>所指定的页面,如果不出错,会直接进行Action::execute()方法 
 
 
十四、struts2默认能解决get和post提交方式的乱码问题吗? 
不能。struts.i18n.encoding=UTF-8属性值只能解析POST提交下的乱码问题。 
 

十五、请你写出struts2中至少5个的默认拦截器? 
fileUpload      提供文件上传功能 
i18n            记录用户选择的locale 
cookies         使用配置的name,value来是指cookies 
checkbox        添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。 
chain           让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。 
alias           在不同请求之间将请求参数在不同名字件转换,请求内容不变 
 
 
十六、值栈ValueStack的原理与生命周期? 
1、ValueStack贯穿整个 Action 的生命周期,保存在request域中,所以ValueStack和request的生命周期一样。当Struts2接受一个请求时,会迅速创建ActionContext, 
ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。 请求来的时候,action、ValueStack的生命开始,请求结束,action、    ValueStack的生命结束; 
2、action是多例的,和Servlet不一样,Servelt是单例的; 
3、每个action的都有一个对应的值栈,值栈存放的数据类型是该action的实例,以及该action中的实例变量,Action对象默认保存在栈顶; 
4、ValueStack本质上就是一个ArrayList; 
5、关于ContextMap,Struts 会把下面这些映射压入 ContextMap 中: 
parameters  :   该 Map 中包含当前请求的请求参数 
request     :   该 Map 中包含当前 request 对象中的所有属性  session :该 Map 中包含当前 session 对象中的所有属性 
application :该 Map 中包含当前 application 对象中的所有属性 
attr:该 Map 按如下顺序来检索某个属性: request, session, application          
6、使用OGNL访问值栈的内容时,不需要#号,而访问request、session、application、attr时,需要加#号; 
7、注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/> 
8、在struts2配置文件中引用ognl表达式 ,引用值栈的值 ,此时使用的"$",而不是#或者%;  
 
 
十七、ActionContext、ServletContext、pageContext的区别? 
1、ActionContext是当前的Action的上下文环境,通过ActionContext可以获取到request、session、ServletContext等与Action有关的对象的引用; 
2、ServletContext是域对象,一个web应用中只有一个ServletContext,生命周期伴随整个web应用; 
3、pageContext是JSP中的最重要的一个内置对象,可以通过pageContext获取其他域对象的应用,同时它是一个域对象,作用范围只针对当前页面,当前页面结束时,pageContext销毁, 
生命周期是JSP四个域对象中最小的。  
 

十八、result的type属性中有哪几种结果类型? 
一共10种:
   
dispatcher         
struts默认的结果类型,把控制权转发给应用程序里的某个资源不能把控制权转发给一个外部资源,若需要把控制权重定向到一个外部资源, 应该使用 
redirect结果类型 
redirect    把响应重定向到另一个资源(包括一个外部资源) 
redirectAction      把响应重定向到另一个 Action 
freemarker、velocity、chain、httpheader、xslt、plainText、stream 
 
 
十九、拦截器的生命周期与工作过程? 
1、每个拦截器都是实现了Interceptor接口的 Java 类; 
2、init(): 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化; 
3、intercept(ActionInvocation invocation): 每拦截一个动作请求, 该方法就会被调用一次; 
4、destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次; 
5、struts2中有内置了18个拦截器。
 

二十、struts2如何完成文件的上传? 
1、JSP页面:
 
1)JSP页面的上传文件的组件:<s: file name=”upload” />,如果需要一次上传多个文件, 就必须使用多个 file 标签, 但它们的名字必须是相同的,即: 
 name=“xxx”的值必须一样; 
2)必须把表单的enctype属性设置为:multipart/form-data; 
 3)表单的方法必须为post,因为post提交的数据在消息体中,而无大小限制。 
2、对应的action:  
 1)在 Action 中新添加 3 个和文件上传相关的属性; 
2)如果是上传单个文件, uploadImage属性的类型就是 java.io.File, 它代表被上传的文件, 第二个和第三个属性的类型是 String, 它们分别代表上传文 
件的文件名和文件类型,定义方式是分别是: 
jsp页面file组件的名称+ContentType,  jsp页面file组件的名称+FileName 
3)如果上上传多个文件, 可以使用数组或 List  

二十一、struts的工作原理
1、初始化,读取struts-config.xml、web.xml等配置文件(所有配置文件的初始化)
2、发送HTTP请求,客户端发送以.do结尾的请求
3、填充FormBean(实例化、复位、填充数据、校验、保存)
4、将请求转发到Action(调用Action的execute()方法)
5、处理业务(可以调用后台类,返回ActionForward对象)
6、返回目标响应对象(从Action返回到ActionServlet)
7、转换Http请求到目标响应对象(查找响应,根据返回的Forward keyword)
8、Http响应,返回到Jsp页面


二十二、用自己的话简要阐述struts2的执行流程。
Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。
核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。
业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。
Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。基本简要流程如下:
1、客户端浏览器发出HTTP请求。
2、根据web.xml配置,该请求被FilterDispatcher接收。
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。
6、返回HTTP响应到客户端浏览器。
它是以Webwork的设计思想为核心,吸收struts1的优点,可以说 struts2是struts1和Webwork结合的产物。

struts2 的工作原理图: 一个请求在Struts2框架中的处理分为以下几个步骤:


1.客户端发出一个指向servlet容器的请求(tomcat);
2.这个请求会经过图中的几个过滤器,最后会到达FilterDispatcher过滤器。
3.过滤器FilterDispatcher是struts2框架的心脏,在处理用户请求时,它和请求一起相互配合访问struts2 的底层框架结构。在web容器启动时,struts2框架会自动加载配置文件里相关参数,并转换成相应的类。 如:ConfigurationManager、ActionMapper和ObjectFactory。ConfigurationManager 存有配置文件的一 些基本信息,ActionMapper存有action的配置信息。在请求过程中所有的对象(Action,Results, Interceptors,等)都是通过ObjectFactory来创建的。过滤器会通过询问ActionMapper类来查找请求中 需要用到的Action。
4.如果找到需要调用的Action,过滤器会把请求的处理交给ActionProxy。ActionProxy为Action的代理对象 。ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类。 5.ActionProxy创建一个ActionInvocation的实例。ActionInvocation在ActionProxy层之下,它表示了 Action的执行状态,或者说它控制的Action的执行步骤。它持有Action实例和所有的Interceptor。 6.ActionInvocation实例使用命名模式来调用,1) ActionInvocation初始化时,根据配置,加载Action相 关的所有Interceptor。2)通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。在 调用Action的过程前后,涉及到相关拦截器(intercepetor)的调用。
7. 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果 通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表 示的过程中可以使用Struts2 框架中继承的标签。



-----------------

1 Struts2与Struts1的联系与区别 为什么要用Struts2
struts1与struts2都是mvc框架的经典实现模式。
Struts2不是从Struts1升级而来,而是有WebWork改名而来,而WebWork只是Xwork加了很多WEB拦截器而已?
区别:
1.核心控制器改成了过滤器(过滤器比Servlet的级别要高,因为程序运行时是先进入过滤器再进入Servlet)
2.struts1要求业务类必须继承Action或dispatchAction,struts2不强制这么做,只需要提供一个pojo类。
3.绑定值到业务类时struts1是通过ActionForm,struts2是通过模型或属性驱动直接绑定到Action属性。
4.struts1严重依赖于Servlet(因为太过于依赖于api的HttpServletRequest与HttpServletResponse的两个参数),
struts2就则脱离了Servlet的API。
5.管理Action时struts1是单例模式,struts2是每个请求产生一个实例。
6.在表达式的支持上struts2不仅有jstl,还有功能更加强大的ognl表达式。
7.struts1的类型转换是单向的(页面到ActionForm),struts2是双向的(页面到Action再到页面回显)
8.校验,struts1没有针对具体方法的校验,struts2提供了指定某个方法进行效验,还有框架校验。
9.struts2提供了拦截器,利用拦截器可以在访问Action之前或之后增加如权限拦截等功能。
10.struts2提供了全局范围,包范围,Action范围的国际化资源文件管理实现。
11.struts2支持多种视图类型,如:jsp,freemaker,velocity,源代码等。
具体区别可以看图形,点击这里
2.Struts2的核心是什么,体现了什么思想
? ?Struts2的核心是拦截器,基本上核心功能都是由拦截器完成,拦截器的实现体现了AOP(面向切面编程)思想?
3 为何继承ActionSupport
答:
因为ActionSupport实现了Action接口,提供了国际化,校验功能。
ActionSupport实现了国际化功能:因为它提供了一个getText(String key)方法实现国际化,该方法从资源文件上获取国际化信息。
Action接口提供了五个常量(success,error,login,input,none)。
4 Struts2 如何定位action中的方法
答:
1 感叹号定位方法(动态方法)。
2 在xml配置文件中通过配置多个action,使用action的method指定方法。
3 使用通配符(*)匹配方法。
5 模型驱动与属性驱动是什么 模型驱动使用时注意什么问题
答:模型驱动与属性驱动都是用来封装数据的。
1.模型驱动:在实现类中实现ModelDriven<T>接口使用泛型把属性类封装起来,重写getModel()方法,然后在实现类里创建一个属性类的实例,
通过这个实例拿到封装进来的值,拿返回值的时候使用工具进行值拷贝。
2.属性驱动:在实现类里定义属性,生成get与set方法,通过属性来拿值。
注意:模型驱动使用时注意的是在使用前先把属性类实例化,否则会出现空指针错误,拿返回对象的值需要用拷贝内存因为地址发生改变。
模型驱动不可以使用局部类型转换器。
3.Struts2是怎样进行值封装的?
struts2的值封装实际上是采用了ognl表达式.
struts2的拦截器经过模型驱动时会先判断action是否实现了ModelDriven,如果是则拿到模型的实例放在了栈的顶部,
到属性驱动的时候会从栈里面把栈顶的实例给取出来,从页面传进来的值放在一个map集合当中,
通过map集合进行迭代会通过ognl技术把值封装到实例中。
6 Struts2如何进行校验
编程校验
1 继承ActionSupport,重写validate方法(针对所有方法)(服务器端编程,不推荐)。
2 validateXxx方法(Xxx代表的是方法名,针对某个方法进行效验)。
3 如果有错误就把错误信息放在FieldError中,并且跳转到指定的错误业务类,没有就会进行action方法的调用。
2 校验框架
每个Action类有一个校验文件,命名 Action类名-validation.xml,且与Action类同目录,这是对action里面所有的方法进行校验。
对Action里面的指定方法做校验使用Action的类名-访问路径_方法名-validation.xml。
如:StudentAction-student_add-validation.xml
在效验文件里又分为两种:
字段校验:字段用什么校验器来校验。
非字段校验:是用校验器校验什么字段。
通俗点讲:字段校验:校验谁,用什么方法。
非字段校验:用什么校验,校验谁 。
?
7 谈谈Struts2 的国际化
答:
在struts2中是使用了拦截器来实现国际化。
struts2的国际化分为三部分:
1.Action范围,这种范围是用Action的实现类的类名来作为前缀__语言名称_国家地区名(大写).properties.
2.包范围,包范围是用package作为前缀__语言名称_国家地区名(大写).properties。
3.全局范围,全局范围的前缀默认的是application,可以通过xml配置文件配置常量(使用constant标签注册i18l拦截器)来指定前缀,
前缀__语言名称_国家地区名(大写).properties。
国际化实现的原理:通过i18n拦截器获得请求参数request——locale的值(zh或者是en)并把当前的值转化为locale对象,
把locale对象存在ww_trans_i18n_locale的session作用域中,根据struts2的请求处理流程,
拦截器只会在进入action的时候才会调用,所有我们一般把对jsp的访问转化为对action的访问。
8 OGNL是什么你在项目中如何使用它
OGNL是:对象图形导航语言。
原ognl是单个对象的,在struts2的应用是多个对象的,struts2的类型转换也是通过ognl来实现的。
Struts2中默认的表达式语言就是ognl,struts2的取值设值都是通过ognl来实现的,struts2要依靠它的标签才可以使用ognl。
相对于jstl或者其他表达式语言,它有如下优势:
1 能够调用对象实例的方法
2 能够调用类的静态方法
3 操作集合对象
4 访问Ognl上下文
取值时ognl有三个参数:1 表达式,2 ognl的上下文(map),3 对象实例(值栈)。
如果表达式带#号是从上下文中(map)拿值,否则是从值栈中拿值。
设值时有四个参数:1 表达式,2 ognl的上下文(map),3 对象实例,4 设入的值
如果表达式带#号是把值设入上下文中(map),否则是把值设入值栈中。
在struts2中 ognl的实现关系:ActionConetxt。
ognl 3个常用的符号 # $ %
# 1 构造map,list集合。
2 取ognl上下文的值。
3 用来过滤集合。
$ 1 在校验框架中取资源文件中的值。
2 可以在配置文件中传递参数。
% 使用百分号可以进行转义。
9 Strust2如何访问Servlet API
答:
1:通过ActionContext可以获得request,application,session三个作用域(struts2实际上是通过适配器来把servlet的api转换为一个map,
并把这些map放在ActionContext里面)。
2:通过ActionContext的子类ServletActionContext去获取原滋原味的API。
3:可以通过实现ServletRequestAware接口,重写里面的setServletRequest方法可以获得request,实际上是通过set的依赖注入。
10 什么是拦截器 说说Struts2用拦截器来干什么 说出6个拦截器来
答:
在访问类的某个方法或者属性之前执行,拦截的是Action的请求,进行拦截然后在方法的执行前或者之后加入某些操作,
如:国际化,权限,效验等与源代码无关的操作。
国际化,表单重复提交,类型转换,自动装配,数据封装,异常处理,模型驱动,请求参数,处理类型转换错误,日志拦截器。
如何实现自定义拦截器?


答:可以继承MethodFilterInterceptor重写doIntercept方法指定某个方法进行拦截,或者继承AbstractInterceptor,重写intercept方法,
在xml配置文件中定义自定义拦截器,然后注入到拦截器栈中,再把拦截器引用到action中。
在把拦截器注入拦截器栈时配置<param>标签,使用name属性配置excludeMethods表示不拦截指定方法。
在配置文件中配置includeMethods指定拦截某个方法。
可以配置到某个action单独使用,也可以配置到包下面的所有action使用。
需要注意什么?
答:注意要把默认的拦截器栈重新引用,否则会被覆盖。
11 项目中遇到什么问题
答:
1.表单重复提交。
在页面使用标签<s:token/>(令牌机制),使用检验表单从复提交的拦截器tokenSession。。
2.国际化必须经过Action
原因:因为国际化是通过i18拦截器来实现的,而拦截器是在访问Action的时候才执行。
解决方式:在对jsp的访问之前进行对action的访问。
3.使用模型驱动拿返回值的时候地址内存不一样,会拿不到值。
原因:因为struts2最开始是把创建action的实例放到ActionContext的栈顶,后来把创建模型驱动的实例放到栈顶,
而通过struts2的标签去取值会取栈顶的实例,而此时拿到的还是最开始的创建的那个实例,所以为空。
解决方式:利用原型进行对象拷贝,使用拷贝工具,BeanUtils或者是propertyUtils。
4.在页面使用转发会报404错。
原因:struts2使用的是filter机制,<jsp:forward/>的机制是servlet。
解决方式:可以通过过滤器改变请求地址,
5.用字符串的时候需要用双引号而不是单引号,单引号在外,双引号在内。
7.当效验出错时,要跳转到相应的页面。
解决方式:使用通配符来解决。
...... 这些问题都可以自己根据实际情况总结
12 ActionContext是用来干什么的
答:ActionContext是Action的上下文。
通过ActionContext这个类来可以获得:request,application,session,Locale、ValueStack,ConversionErrors
1 可以获得servlet的api:request,application,session。
2 进行国际化:获得语言环境 Locale。
3 收集错误信息:ConversionErrors。
4 有个值栈来装action实例与创建的模型驱动的实例:ValueStack。
5 ActionContext是线程安全的-用本地线程实现的。
13 Struts2是如何实现mvc的:struts2的底层视图默认是freemaker。
什么mvc?
M:模型,V:视图,C:控制器
在struts2中分别对应什么?
M(模型):除核心控制器外都属于模型,实现业务的类(service层与dao层)。
V(视图):result,type,dispatcher默认的(jsp,freemaker,velocity,源代码等)。
C(控制器):核心控制器与业务控制器。
mvc解决什么问题?
解决了数据封装,类型转换,数据效验,国际化,异常处理等问题。
14.为什么要继承默认的包?
? ? ?因为在Strtus2里面默认有很多的常量,拦截器,还有一些bean,如果继承默认的包,这些默认值和常量就会继承过来,?
15 .常见的有那些有十几种结果集类型,
常见的结果集类型有dispatcher,redirect,redirectAction,stream等
默认的是dispatcher,值得是转发
redirect指重定向,
redirectAction是重定向到一个Action
stream是返回一个流,一般用在文件下载上面
16 开发项目时struts2在页面怎样拿值?
从值栈中或者是ognl的上下文
17.怎么样用Struts2进行文件的上传或者下载
? ?Struts2里面已经提供了默认的拦截器来处理上传,只要在jsp用了s:file标签,把s:from的enctype 属性设置为 multipart/form-data,然后在action里面定义三个字段 File file ,String [file]ContentType,String [file]?FileName即可,如果有多个文件上传,那么就用List<File>来接受,然后把接受到的File构建成FileInputStream,转化成硬盘上面的文件即可(用输出流)
下载用了resust为stream的类型,然后在action定义四个属性,默认的有个是InputStream 的类型叫inputStream的,从硬盘上面读取文件到这个流赋值即可.
18.简单讲下struts里面的标签,说不少于5个
s:iterater ?s:property s:form s:url s:if 等等
19.默认struts2里面的标签取值都是从那里取值的
默认都是从OGNL值栈里面取值的?
21.ValueStack分为那两部分,组成部分是什么,分别怎么访问
?分为对象栈和ContextMap ,对象栈里面放入的是Action及其用户定义的对象,在前台可以直接访问,在contextMap里面放入的是Servlet对象转化后map,譬如requestMap,sessionMap,访问的时候前面加#即可.?
22.标签<s:property>和el表达式有什么区别,
它们都可以从值栈里面取值,但是el表达式只能取属性有get set方法的简单数据类型,如果要取得数组的一些方法等复杂数据对象类型,那么就要用s:property标签
23 struts2的请求处理流程
答:
1.客户端发送请求。
2.经过一系列的过滤器(如:ActionContextCleanUp、SiteMesh等)到达核心控制器(FilterDispatcher)。
3.核心控制器通过ActionMapper决定调用哪个Action,如果不是调用Action就直接跳转到jsp页面。
4.如果ActionMapper决定调用了某个Action,核心控制器就把请求的处理交给一个代理类(ActionProxy)。
5.代理类通过配置管理器(Configuration Manager)找到配置文件(struts.xml)找到需要调用的Action类。
6.代理类还要创建一个Action的调度器(ActionInvocation)。
7.由调度器去调用Action,当然这里还涉及到一些相关的拦截器的调用。
8.Action执行完后,这个调度器还会创建一个Result返回结果集,返回结果前还可以做一些操作(结果集前的监听器)。
21.struts2源码与设计模式(讲完设计模式再回顾,暂不面试)
答:
命令模式(发生.do请求封装成action调用execute方法),代理模式(访问action时核心控制器把请求交给代理类(ActionProxy)去访问Action就是代理模式),
责任链模式(访问action时经过一系列的拦截器就使用了责任链模式),适配器(把Servlet的API通过适配器转换成Map,把Map放入ActionContext中),
组合模式(拦截器栈和拦截器就使用到组和模式)。
源码:
服务器启动的时候容器会创建FilterDispatcher实例,进入dispatcher.init()方法,在init方法里面会初始化sturts2的一系列的配置文件,
然后向服务器发送请求,进入doFilter方法,在里面通过调用dispatcher.serviceAction方法,进入到Dispatcher里面的serviceAction方法,
在这里就会把servlet的api转换为map,并把它一个个的放在ActionContext中,在这里还会创建ActionProxy的实例去调用execute方法,
到StrutsActionProxy的execute方法,通过DefaultActionInvocation的实例去调用invoke方法,在invoke方法里面会进行判断拦截器是否存在,
如果存在就会调用intercept方法,在拦截器类(Intercept)中会通过DefaultActionInvocation实例调用里面的invock方法,它们会形成递归调用,
当拦截器不存在的时候就会进入invokeActionOnly方法,判断有没有返回结果前的监听器preResultListener如果有则进去一个个执行,
最后调用 executeResult()方法,创建result返回,执行execute方法,并返回视图。


----------------------------------

1)Struts2中的Action是线程安全的吗?
2)Servlet是线程安全的吗?
3)一个Action只能处理一个请求吗?
1)Struts2中的Action是线程安全的,每个请求都会创建单独的Action类来处理请求。
2)Servlet并不是线程安全的,是单例模式开发,如果有共享变量,要注意线程安全。
3)一个Action是可以处理多个请求的,通过配置不同的method和创建不同的method



-------------------------------------------

1、Struts2框架在三层架构中哪部分进行的再优化?

表现层进行的再优化。

三层架构:

表现层 MVC

业务层 service

持久层 dao(data access object)

 

2、Struts1和Struts2的一个显著区别是什么?

Struts1的核心控制器是一个servlet。

Struts2的核心控制器是一个过滤器。

 

3、Struts2的编写步骤?

1.导入相关jar包

2.配置web.xml中的过滤器

3.编写struts.xml

4.开发action。

 

4、Struts2的执行过程?

tomcat启动的时候加载应用的web.xml,实例化并初始化过滤器,过滤器的初始化方法加载struts.xml。客户端发送请求,请求到达过滤器,截取请求的动作名称(没有或以action结尾),并从struts.xml中找,找到后,实例化动作类。调用对应的动作方法,方法有返回值,根据返回值,找到name取值对应的结果视图,找到jsp页面。 

 

5、Struts2的配置文件加载时机和加载顺序?

当应用被tomcat加载的时候,struts2的配置文件就已经被加载过了。加载顺序:default.propertiesstruts-default.xmlstruts-plugin.xmlstruts.xmlweb.xml

 

 

6、常量中struts.devMode是什么意思,如何配置?

开发模式。修改了struts.xml中的配置,你不必每次都重启服务器。

<constant name="struts.devMode" value="true" />

 

7、struts.xml配置文件中package的四个属性分别什么意思?

name:包名

extends:一般是继承struts-default包,但不是必须的。不过如果不继承的话,将无法使用struts2提供的核心功能。

abstract:把包声明为抽象包,抽象包就是用来被继承的。只要是没有<action>元素的包,就可以声明为抽象包。

namespace:名称空间。

 

8、访问带有名称空间的动作时,是如何查找的? /user/abc/action1.action

先找user/abc,有action1就执行,没有再找user下面的action1,有就执行,最后找根目录。

 

9、action元素的三个属性什么意思

name:动作名称

class:动作类全名。默认的动作类是:com.opensymphony.xwork2.ActionSupport是在struts-default.xml中定义的。

method:动作类中的方法名称。默认是public String execute(){}

要求:

1.public

2.返回值必须是String

3.没有参数

 

10、result元素的两个属性分别指的是什么?

name:逻辑视图的名称,对应着动作方法的返回值。默认值是success。 

type:结果类型,指的就是用什么方式转到定义的页面。默认是dispatcher。

 

11、4个常用结果类型分别是什么?

dispatcher:(默认值)使用请求转发,转向一个页面。

redirect:使用重定向,转向一个页面。

redirectAction:注意:使用的是重定向。

a.重定向到另一个相同名称空间的动作。b.重定向到不同名称空间的动作

chain:注意:使用的是请求转发。

a.转发到另一个相同名称空间的动作。b.请求转发到不同名称空间的动作

 

12、访问ServletAPI的两种方式?

第一种方式:使用ServletActionContext

第二种方式:使用实现接口的方式(ServletRequestAwareServletResponseAware

 

1、如何封装静态请求参数?

struts.xml配置文件中,给动作类注入值。调用的是setter方法。

 

2、动作类和模型分开的动态封装请求参数,setget方法是怎么调用的?

get出来,判断存不存在,存在直接get第二次(给这个对象赋值),不存在(把这个对象创建出来,set回去,然后再get出来)

 

3、使用模型驱动动态封装请求参数的要求是什么?

实现ModelDriven接口,动作类和实体模型分开,创建模型对象并将其实例化,重写getModel方法,返回一个引用。

 

4、实际开发中类型转换的两种情况是什么?

转字符串,转其他类型。

写的时候,发送请求,经过过滤器,最后到数据库,字符串转其他类型。

读的时候,到页面,其他类型转成字符串

 

5、Struts2中提供的常用类型转换分几类?

      a.基本数据类型自动转换。

b.日期类型:默认按照本地日期格式转换(yyyy-MM-dd)。

c.字符串数组:默认用逗号+空格,连接成一个字符串

 

6、自定义类型转换器是如何注册的?(两种情况)

局部类型转换器:只能指定javabean中的属性用

      按照属性来注册。在属性所属的javabean的包下建立一个.properties文件。文件名称:javabean名称-conversion.properties

全局类型转换器:(推荐)

按照要转换的数据类型来注册。at the top op classpath,建立一个固定名称xwork-conversion.properties的属性文件。

 

7、如何解决编程式验证动作类中的全部动作方法都验证?

在动作类中覆盖public void validate()方法。

 

8、声明式验证的分别可以基于什么?

基于字段和验证器。


9、命名声明式验证xml文件名的两种方式,有什么不同?

a.针对动作类中的所有动作进行验证:在动作类所在的包中,建立一个ActionClassName-validation.xml的文件

   b、针对动作类中的某个动作进行验证:在动作类所在的包中建立一个xml文件,名称为ActionClassName-ActionName-validation.xml

 

1、国际化的消息资源文件如何命名?

一个资源包由多个文件组成,这些文件名都有命名规范:主要文件名_语言代码_国家代码.properties

语言代码:由iso规定的。国家代码:有iso规定的当文件只有主要文件名.properties时,表明它是默认资源包。浏览器会根据不同的语言环境找对应语言环境的资源包,当没有时,找默认的。

每个资源包的内容都由相同的key和对应语言环境的value组成。

比如:

message_zh_CN.properties   message_zh_HK.properties message_en_US.properties

 

   2、 Struts2中全局,动作范围和包范围,哪个加载优先级高?页面上如何读取指定的消息资源包?

动作范围。

 

3、Struts2中拦截器的执行时机?

拦截动作方法之前,正序执行;拦截动作方法之后,倒序执行。

 

4、自定义拦截器的步骤是什么?

a、编写一个类,继承AbstractInterceptor类或者实现Interceptor接口。重写intercept方法。

b配置拦截器:注意拦截器必须先声明再使用

 

5、多个拦截器如何确定执行顺序?

使用顺序。

 

6、自定义拦截器除了继承AbstractInterceptor还可以继承哪个?另一个有什么好处?

可以继承MethodFilterInterceptor并且重写doIntercept方法。

通过参数注入的方式,哪个拦截和不拦截。

 

7、文件上传是哪个拦截器为我们做的?如何限定上传文件的大小和类型?

fileupload拦截器

   在struts.xml中改变default.properties文件中的常量。

fileUpload拦截器注入参,数通过限制上传文件的MIME类型

 

8、struts2中文件下载是由哪个结果类型完成的?需要我们提供什么参数?

stream类型。输入流的字段名称(inputname)、文件类型(contentType)、响应消息头(contentDisposition


 

9、OGNL是什么?使用它能否访问普通方法?能否直接访问静态方法?

OGNLObject Graphic Navigation Language(对象图导航语言)的缩写,它是一个单独的开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

可以直接访问普通方法。不能直接访问静态方法。需要在struts.xml中启用。

 

10、ActionContextValueStack什么时候创建?是否是线程安全的?

明确:动作类是多例的,每次动作访问,动作类都会实例化。所以是线程安全的。Struts1的区别是,struts1的动作类是单例的。

在每次动作执行前,核心控制器StrutsPrepareAndExecuteFilter都会创建一个ActionContextValueStack对象。且每次动作访问都会创建。

      这两个对象存储了整个动作访问期间用到的数据。并且把数据绑定到了线程局部变量(ThreadLocal)上了。所以是线程安全的。

 

 

11、ContextMap中的结构是什么样的?

除了value stack之外,全是map,而contextMap也是一个map。其实就是Map中又封装的Map。(很像dbutilsKeyedHandler封装数据的结构,只是封装数据的结构)


-----------------

Struts2配置文件加载顺序

    通过查看StrutsPrepareAndExecuteFilter源码可以得到答案!
        82dc781d-960c-4ea8-81d9-9055e7e9c44c   
    此处,我们以及清晰了看到了该类加载配置文件的顺序,我们依次围绕标号查看对应方法产生的文件即可。

 

    be5b51bc-149e-4e9a-baaf-1db4992d7cf9

-------------------------

拦截器和过滤器有什么区别?

1、①拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
拦  拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。


原创粉丝点击