第一部分 Java基础
第二部分 Java进阶

Java struts2面试题及答案

1、简单介绍一下Struts2?

Struts2框架是一个按照MVC设计模式设计的WEB层框架,是在Struts 1和WebWork的技术基础上进行了合并的全新的框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开。

我们可以把Struts2理解为一个大大的Servlet,而这个Servlet就是ActionServlet。Struts2在处理客户端请求时,会先读取web.xml配置文件,根据前端控制器将符合条件的请求分给各个不同的Action处理。在此之前,ActionServlet会把数据封装成一个JavaBean。

Struts2框架提供了许多的拦截器,在封装数据的过程中,我们可以对数据进行一些操作,例如:数据校验等等。当Action执行完后要返回一个结果视图,这个结果视图可以跟据struts2的配置文件中配置,选择转发或者重定向。

2、Struts2的执行流程了解么?

● 关于图中的Key:

Servlet Filters:过滤器链,客户端的所有请求都要经过Filter链的处理。

● Struts Core:Struts2的核心部分

Interceptors:Struts2的拦截器。Struts2提供了很多默认的拦截器,可以完成日常开发的绝大部分工作;而我们自定义的拦截器,用来实现实际的客户业务需要的功能。

User Created:由开发人员创建的,包括struts.xml、Action、Template,这些是每个使用Struts2来进行开发的人员都必须会的。

● FilterDispatcher是整个Struts2的调度中心,也就是MVC中的C(控制中心),根据ActionMapper的结果来决定是否处理请求,如果ActionMapper指出该URL应该被Struts2处理,那么它将会执行Action处理,并停止过滤器链上还没有执行的过滤器。

● ActionMapper会判断这个请求是否应该被Struts2处理,如果需要Struts2处理,ActionMapper会返回一个对象来描述请求对应的ActionInvocation的信息。

● ActionProxy会创建一个ActionInvocation实例,位于Action和xwork之间,使得我们在将来有机会引入更多的实现方式,比如通过WebService来实现等。

● ConfigurationManager是xwork配置的管理中心,可以把它看做struts.xml这个配置文件在内存中的对应。

● struts.xml是开发人员必须光顾的地方。是Stuts2的应用配置文件,负责诸如URL与Action之间映射关系的配置、以及执行后页面跳转的Result配置等。

● ActionInvocation是真正调用并执行Action,它拥有一个Action实例和这个Action所依赖的拦截器实例。

● ActionInvocation会按照指定的顺序去执行这些拦截器、Action以及相应的Result。

● Interceptor(拦截器):是Struts2的基石,类似于JavaWeb的Filter,拦截器是一些无状态的类,拦截器可以自动拦截Action,它们给开发者提供了在Action运行之前或Result运行之后来执行一些功能代码的机会。

● Action:用来处理请求,封装数据。

3、Struts2中Action配置的注意事项有哪些?

● name包名称,在struts2的配置文件中,包名不能重复,name并不是真正包名,只是为了管理Action

● namespace和<action>的name属性,决定Action的访问路径(以/开始)

● extends继承哪个包,通常开发中继承struts-default包(struts-default包在struts-default.xml中定义)

4、拦截器和过滤器有哪些区别?

● 拦截器是基于java的反射机制的,而过滤器是基于函数回调​​​​​​​

● 拦截器不依赖与servlet容器,而过滤器依赖与servlet容器​​​​​​​

● 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用​​​​​​​

● 拦截器可以访问action上下文、值栈里的对象,而过滤器不能​​​​​​​

● 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

5、Struts2的封装方式有哪些?

● 属性封装

在action中设置成员变量,变量名与表单中的name属性值相同

生成变量的set方法​​​​​​​

实例:获取用户输入的用户名和密码

● jsp页面如下:

<form action="hello" method="post">
userName<input type="text" name="userName">
userPwd<input type="password" name="userPwd">
<input type="submit" value="submit">
</form>

● java代码如下:

private String userName;
private String userPwd;
public String excute() {
    System.out.println("userName" + " " + "userPwd");
    return NONE;
}
public void setUserName(String userName) {
    this.userName = userName;
}
public void setUserPwd(String userPwd) {
    this.userPwd = userPwd;
}

 ​​​​​​​6、简单介绍一下Struts2的值栈?

值栈是对应每一个请求对象的数据存储中心。Struts2的一个很重要的特点就是引入了值栈。之前我们通过缓存或者模型驱动在action和页面之间传递数据,数据混乱,并且难以管理,缓存还有时间和数量限制,使用起来非常的困难。值栈的引入解决了这个问题,它可以统一管理页面和action之间的数据,供action、result、interceptor等使用。我们大多数情况下不需要考虑值栈在哪里,里面有什么,只需要去获取自己需要的数据就可以了,大大的降低了开发人员的工作量和逻辑复杂性。

​​​​​​​7、SpringMVC 和 Struts2 的区别?

Struts2是类级别的拦截,一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现Restful url,而Struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。​​​​​​​

● SpringMVC的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过Model Map交回给框架,方法之间不共享变量,而Struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码读程序时带来麻烦,每次来了请求就创建一个Action,一个Action对象对应一个request上下文。​​​​​​​

● Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,Struts2是比较耗费内存的。​​​​​​​

● 拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。​​​​​​​

● SpringMVC的入口是Servlet,而Struts2是filter(这里要指出,filter和servlet是不同的),这就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。​​​​​​​

● SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。​​​​​​​

● SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。Spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。​​​​​​​

● 设计思想上,Struts2更加符合OOP的编程思想,SpringMVC就比较谨慎,是servlet上扩展。​​​​​​​

● SpringMVC开发效率和性能高于Struts2,SpringMVC可以认为已经100%零配置。

8、Struts2中的#和%分别是做什么的?******

(1)使用#获取 context 里面数据

<s:iterator value= "list"  var="user">
    <s:property value= "#user.username">
</s:iterator>

(2)向 request 域放值(获取 context 里面数据,写 ognl 时候,首先添加符号#context 的 key 名称.域对象名称)

(3)在页面中使用 ognl 获取

<s:property  value = "#request.req">

(4)%在 struts2 标签中表单标签

在 struts2 标签里面使用 ognl 表达式,如果直接在 struts2 表单标签里面使用 ognl 表达式不识别,只有%之后才会识别。​​​​​​​

<s:textfield name="username" value="%{#request.req}">

9、​​​​​​​Struts2中有哪些常用结果类型?​​​​​​​

● dispatcher:默认的请求转发的结果类型,Action转发给JSP​​​​​​​

● chain:Action转发到另一个Action(同一次请求)​​​​​​​

● redirect:重定向,重定向到一个路径信息,路径信息没有限制(不在一个请求中),Action重定向到JSP 4)redirectAction:Action重定向到另一个Action​​​​​​​

● stream:将原始数据作为流传递回浏览器端,该结果类型对下载的内容和图片非常有用。​​​​​​​

● freemarker:呈现freemarker模板。​​​​​​​

● plaintext:返回普通文本内容。​​​​​​​​​​​​​​

全部教程