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 模型驱动与属性驱动是什么 模型驱动使用时注意什么问题

5.模型驱动和属性驱动的区别是什么?

答:模型驱动与属性驱动都是用来封装数据的。
1.模型驱动:在实现类中实现ModelDriven<T>接口使用泛型把属性类封装起来,重写getModel()方法,然后在实现类里创建一个属性类的实例,
通过这个实例拿到封装进来的值,拿返回值的时候使用工具进行值拷贝。
2.属性驱动:在实现类里定义属性,生成get与set方法,通过属性来拿值。
注意:模型驱动使用时注意的是在使用前先把属性类实例化,否则会出现空指针错误,拿返回对象的值需要用拷贝内存因为地址发生改变。

模型驱动不可以使用局部类型转换器。


6.Struts2是怎样进行值封装的?

    答:struts2的值封装实际上是采用了ognl表达式.
    struts2的拦截器经过模型驱动时会先判断action是否实现了ModelDriven,如果是则拿到模型的实例放在了栈的顶部,
    到属性驱动的时候会从栈里面把栈顶的实例给取出来,从页面传进来的值放在一个map集合当中,

    通过map集合进行迭代会通过ognl技术把值封装到实例中。


7. 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
    在效验文件里又分为两种:
    字段校验:字段用什么校验器来校验。
    非字段校验:是用校验器校验什么字段。
    通俗点讲:字段校验:校验谁,用什么方法。
    非字段校验:用什么校验,校验谁 。

8.谈谈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的访问。


9.    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 可以在配置文件中传递参数。

    % 使用百分号可以进行转义。


10.Strust2如何访问Servlet API

    答:
    1:通过ActionContext可以获得request,application,session三个作用域(struts2实际上是通过适配器来把servlet的api转换为一个map,
    并把这些map放在ActionContext里面)。
    2:通过ActionContext的子类ServletActionContext去获取原滋原味的API。

    3:可以通过实现ServletRequestAware接口,重写里面的setServletRequest方法可以获得request,实际上是通过set的依赖注入。


11.什么是拦截器 说说Struts2用拦截器来干什么 说出6个拦截器来

    答:
    在访问类的某个方法或者属性之前执行,拦截的是Action的请求,进行拦截然后在方法的执行前或者之后加入某些操作,
    如:国际化,权限,效验等与源代码无关的操作。

    国际化,表单重复提交,类型转换,自动装配,数据封装,异常处理,模型驱动,请求参数,处理类型转换错误,日志拦截器。


12.如何实现自定义拦截器?

    答:可以继承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返回结果集,返回结果前还可以做一些操作(结果集前的监听器)。



猜你喜欢

转载自blog.csdn.net/godlk/article/details/80761550