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方法,并返回视图。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值