Struts2面试题

1. 简述 Struts2 的工作流程 :

答案:

  1. 请求发送给 StrutsPrepareAndExecuteFilter
  2. StrutsPrepareAndExecuteFilter过滤器拦截该请求并判定该请求是否是一个 Struts2 请求
  3. 若该请求是一个 Struts2 请求(ActionMapping),则 StrutsPrepareAndExecuteFilter把请求的处理交给 ActionProxy
  4. ActionProxy 创建一个 ActionInvocation 的实例,并进行初始化,当然在这之前ActionProxy还会通过ConfigurationManager按加载struts2的配置文件(Action和Interceptors)
  5. ActionInvocation 实例在调用 Action 的过程前后,涉及到相关拦截器(Intercepter)的调用。
  6. Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。调用结果的 execute 方法,渲染结果。
  7. 执行各个拦截器 invocation.invoke() 之后的代码
  8. 把结果发送到客户端

解析:

Struts2工作流程-官方图:

 **Struts2工作流程-官方图**

简化版Struts2工作流程图:

​ 这是我通过查找资料画的简化版Struts2工作流程图,会比官方的图好记忆。

Struts2工作流程图

2. Struts2拦截器和过滤器的区别:

答案:

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

解析:

  1. 什么是拦截器?

在AOP中用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。 AOP基本上是通过代理模式实现的

拦截器aop编程

​ 重复代码,横向抽取

拦截器aop编程

  1. 什么是过滤器?

过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。.滤器用到了责任链的设计模式

filter的访问流程图

filter的访问流程图

3. 为什么要使用 Struts2 & Struts2 的优点?

答案:

  1. 基于 MVC 架构,框架结构清晰,使开发者只关注业务逻辑的实现
  2. 与OGNL结合使用:OGNL 可以快捷的访问值栈中的数据、调用值栈中对象的方法
  3. 提供丰富的拦截器实现:Struts2 的拦截器是一个 Action 级别的 AOP,Struts2 中的许多特性都是通过拦截器来实现的,例如异常处理,文件上传,验证等。拦截器是可配置与重用的
  4. Struts2的可扩展性高:可以自定义拦截器,用户开发了插件只要很简单的配置就可以很容易的和Struts2框架融合,这实现了框架对插件的可插拔的特性
  5. 异常处理机制:只需在配置文件中配置异常的映射,即可对异常做相应的处理

4. Struts2 如何访问 HttpServletRequest、HttpSession、ServletContext三个域对象?

答案:

  1. 通过 ActionContext 访问域对象对应的 Map 对象
  2. 通过 ServletActionContext 直接获取 Servlet API 对象
  3. 通过实现接口方式(例如:ServletRequestAware、ServletResponseAware等)

解析:

1. Struts2访问ServletAPI原理图:

img

2. 通过ActionContext
//如何在action中获得原生ServletAPI
public class DemoTestAction extends ActionSupport {

	public String execute() throws Exception {
		//request域=> map (struts2并不推荐使用原生request域)
		//因为request域和actioncontext域的生命周期是一样的,并且struts包装了request域,建议用ActionContext
		//不推荐使用
		Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
		//推荐使用(Struts核心过滤器已经对request对象进行过包装,改变了取值位置,即会找request,也会继续找ActionContext)
		ActionContext.getContext().put("name", "requestTom");
		//session域 => map
		Map<String, Object> sessionScope = ActionContext.getContext().getSession();
		sessionScope.put("name", "sessionTom");
		//application域=>map
		Map<String, Object> applicationScope = ActionContext.getContext().getApplication();
		applicationScope.put("name", "applicationTom");
		
		return SUCCESS;
	}

}
3. 通过ServletActionContext(不推荐)
//如何在action中获得原生ServletAPI
public class Demo6Action extends ActionSupport {
	//并不推荐,其实也是从ActionContext中获得的,而且struts本来就希望你脱离原生的session类
	public String execute() throws Exception {
		//原生request
		HttpServletRequest request = ServletActionContext.getRequest();
		//原生session
		HttpSession session = request.getSession();
		//原生response
		HttpServletResponse response = ServletActionContext.getResponse();
		//原生servletContext
		ServletContext servletContext = ServletActionContext.getServletContext();
		return SUCCESS;
	}
	
} 
4. 通过实现接口方式(不推荐)
//如何在action中获得原生ServletAPI
public class DemoTestAction extends ActionSupport implements ServletRequestAware {
	
	
	private HttpServletRequest request;

	public String execute() throws Exception { 
		
		System.out.println("原生request:"+request);
		return SUCCESS;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	
}

5. Struts2中的默认包struts-default有什么作用?

答案:

  1. struts-default 包是 struts2 内置的,它定义了 struts2 内部的众多拦截器和 Result 类型,而 Struts2 很多核心的功能都是通过这些内置的拦截器实现,如:从请求中把请求参数封装到 action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了 struts-default 包才能使用 struts2 为我们提供的这些功能
  2. struts-default 包 是 在 struts-default.xml中定义,struts-default.xml 也是 Struts2 默认配置文件 Struts2 每次都会自动加载 struts-default.xml 文件。
  3. 通常每个包都应该继承 struts-default 包

6. 说出Struts2中至少5个的默认拦截器

答案:

exception、fileUpload、i18n、modelDriven、params、prepare、validation 等

解析:

<interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
            <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
            <interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"/>
            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
            <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
            <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
            <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
            <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
            <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
            <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
            <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
            <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
            <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
            <interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
            <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
            <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
            <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
            <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
            <interceptor name="deprecation" class="org.apache.struts2.interceptor.DeprecationInterceptor" />

拦截器栈对应的拦截器

已配置栈名 包含的拦截器 描 述
basicStack exception、servletConfig、prepare、checkbox、params、conversionError 如使用栈,最起码要使用这几个拦截器
validationWorkflowStack basicStack、validation、workflow 在基本栈的基础上增加验证和工作流特性
fileUploadStack fileUpload、basicStack 在基本栈的基础上增加文件上传特性
modelDrivenStack modelDriven、basicStack 在基本栈的基础上增加模型功能特性
chainStack chain、basicStack 在基本栈的基础上增加链接特性
i18nStack i18n、basicStack 在基本栈的基础上增加区域持久化特性
paramPrepareParamsStack exception、alias、params、servletConfig、prepare、i18n、chain、modelDriven、file- Upload、checkbox、staticParams、params、conversionError、vali- dation、workflow 提供包括前action(pre-action)方法调用的完整栈。params栈使用两次:第一次是在调用prepare()方法之前提供参数,第二次是在预备阶段为可能被检索的对象重新使用参数
defaultStack exception、alias、servlet- Config、prepare、i18n、chain、debugging、profiling、scoped- ModelDriven、modelDriven、fileUpload、checkbox、static- Params、params、conversion- Error、validation、workflow 提供一个完整栈,包括调试和概要
executeAndWaitStack execAndWait、defaultStack、execAndWait 提供执行与等待栈,比如在上传文件时需要向用户显示一个等待页面时,就可以使用这个栈

7. 谈谈你对ValueStack的理解

答案:

  1. ValueStack 贯穿整个 Action 的生命周期,保存在 request 域中,所以 ValueStack 和 request 的生命周期一样。 当Struts2收到一个请求时,会迅速创建 ActionContext、ValueStack、Action;然后把 Action 存放进ValueStack;最后再把值栈对象放入request中,传入jsp页面。所以 Action 的实例变量可以被OGNL访问。
  2. 值栈是多实例的,因为 Action 是多例的(和 Servlet 不一样,Servelt是单例的),
  3. 每个 Action 都有一个对应的值栈,Action 对象默认保存在栈顶
  4. ValueStack 本质上就是一个 ArrayList(查看源代码得到)

解析:

Struts2和OGNL表达式结合原理图

Struts2和OGNL表达式结合原理图

Root:默认情况下,栈中放置当前访问的Action对象

DEBUG标签下的root

Context:Context部分就是ActionContext数据中心

8. ActionContext 、ServletContext 、pageContext的区别?

答案:

  1. ActionContext Struts2 的 API:是当前的 Action 的上下文环境,通过ActionContext可以获取到request、session、ServletContext等与Action有关的对象的引用
  2. ServletContext是域对象,一个web应用中只有一个ServletContext,生命周期伴随整个web应用
  3. pageContext是JSP中的最重要的一个内置对象,可以通过pageContext获取其他域对象的应用,同时它是一个域对象,作用范围只针对当前页面,当前页面结束时,pageContext销毁, 生命周期是JSP四个域对象中最小的

9. Struts2有哪几种结果类型?

答案:

dispatcher(转发)、redirect(重定向)、chain(转发到某个action上)、redirectAction(重定向到某个action上)等

参看 struts-default.xml 中的相关配置:

<package name="struts-default" abstract="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
            <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
        </result-types>

10. struts2是如何管理action的?这种管理方式有什么好处?

答案:

Struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的

主要用于管理一组业务功能相关的action。在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下

posted @ 2018-11-29 20:37  薄荷叶cc  阅读(741)  评论(1编辑  收藏  举报