Struts2面试问题

article/2025/9/30 13:10:58

转载自   Struts2面试问题

1.什么是Struts2?

Apache Struts2是一个用Java构建Web应用程序的开源框架。Struts2基于OpenSymphony WebWork框架。它从Struts1中得到了很大的改进,使其更加灵活,易于使用和扩展。Struts2的核心组件是Action,Interceptors和Result页面。

Struts2提供了许多方法来创建Action类并通过struts.xml或注释来配置它们。我们可以为常见任务创建自己的拦截器。Struts2附带了很多标签,并使用OGNL表达式语言。我们可以创建自己的类型转换器来渲染结果页面。结果页面可以是JSP和FreeMarker模板。

 

2.Struts2的核心组件是什么?

 

Struts2的核心组件是:

动作类 拦截器 结果页面,FreeMarker模板的JSP ValueStack,OGNL和Tag Libraries Struts 2架构图,struts2   ,struts2试题

 

3.什么是Struts2中的拦截器?

拦截器是Struts2 Framework的支柱。Struts2拦截器负责框架完成的大部分处理,例如将请求参数传递给动作类,使Servlet API请求,响应,会话可用于Action类,验证,i18n支持等。

ActionInvocation负责封装Action类和拦截器并按顺序触发它们。在ActionInvocation中使用的最重要的方法是invoke()方法,它跟踪拦截器链并调用下一个拦截器或动作。这是Java EE框架中责任链模式的最佳示例之一。

 

4.Struts2拦截器实现了哪种设计模式?

Struts2拦截器基于拦截滤波器设计模式。拦截器堆栈中拦截器的调用非常类似于责任链设计模式。

 

5.在Struts2中创建Action类有哪些不同的方法?

Struts2提供了创建动作类的不同方法。

通过实现Action接口 使用Struts2 @Action注释 通过扩展ActionSupport类 任何返回String的execute()方法的普通java类都可以配置为Action类。

 

6.Struts2动作和拦截器是否是线程安全的?

Struts2 Action类是线程安全的,因为对象是为每个处理它的请求实例化的。

Struts2拦截器是单例类,并且创建了一个新线程来处理请求,因此它不是线程安全的,我们需要仔细实现它们以避免共享数据的任何问题。

 

7.哪个类是Struts2中的前端控制器?

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter是Struts2中的Front Controller类,每个请求处理都从这个类开始。早期版本的Struts2 org.apache.struts2.dispatcher.FilterDispatcher用作Front Controller类。

 

8.Struts2中拦截器有哪些好处?

拦截器的一些好处是:

拦截器在实现高度分离关注方面起着至关重要的作用。

Struts2拦截器是可配置的,我们可以为我们想要的任何动作配置它。

我们可以创建自己的自定义拦截器来执行一些常见任务,例如请求参数记录,身份验证等。这有助于我们在一个位置处理常见任务,从而降低维护成本。

我们可以创建拦截器堆栈以用于不同的操作。

 

9.什么是ValueStack和OGNL?

ValueStack是Struts2存储应用程序数据以处理客户端请求的存储区域。数据存储在ActionContext使用ThreadLocal的对象中,以具有特定于特定请求线程的值。

对象图导航语言(OGNL)是一种功能强大的表达式语言,用于处理存储在ValueStack上的数据。正如您在架构图中看到的,拦截器和结果页面都可以使用OGNL访问存储在ValueStack上的数据。

 

10.列举Struts2中引入的一些有用的注释?

Struts2中引入的一些重要注释是:

  1. @Action创建动作类

  2. @Actions为多个动作配置单个类

  3. @Namespace和@Namespaces用于创建不同的模块

  4. @Result用于结果页面

  5. @ResultPath用于配置结果页面位置

 

11.提供一些您使用过的重要Struts2常量?

  1. struts.devMode在开发模式下运行我们的应用程序。此模式会重新加载属性文件,并提供额外的日志记录和调试功能。它在开发我们的应用程序时非常有用,但我们应该在将代码转移到生产时将其关闭。

  2. struts.convention.result.path用于配置结果页面的位置。默认情况下,Struts2在{WEBAPP-ROOT} / {Namespace} /中查找结果页面,我们可以使用此常量更改位置。

  3. struts.custom.i18n.resources为i18n支持定义全局资源包。

  4. struts.action.extension为Struts2应用程序配置URL后缀。默认后缀是.action但有时我们可能想将其更改为.do或其他内容。

我们可以在struts.xml文件中配置上面的常量,如下所示。

<constant name="struts.devMode" value="true"></constant>
<constant name="struts.action.extension" value="action,do"></constant>
<constant name="struts.custom.i18n.resources" value="global"></constant>
<constant name="struts.convention.result.path" value="/"></constant>

 

12.Struts2中动作映射中命名空间的用途是什么?

Struts2命名空间配置允许我们轻松创建模块。我们可以使用命名空间根据其功能分离我们的操作类,例如admin,user,customer等。

 

13.哪个拦截器负责将请求参数映射到动作类Java Bean属性?

com.opensymphony.xwork2.interceptor.ParametersInterceptor拦截器负责将请求参数映射到Action类的java bean属性。此拦截器在struts-default包中配置,名称为“params”。此拦截器是basicStack和defaultStack拦截器堆栈的一部分。

 

14.哪个拦截器负责i18n支持?

com.opensymphony.xwork2.interceptor.I18nInterceptor拦截器负责Struts2应用程序中的i18n支持。此拦截器在struts-default包中配置,名称为“i18n”,它是i18nStack和defaultStack的一部分。

 

15.对我们的操作类使用Action接口和ActionSupport类有什么区别,您更喜欢哪一个?

我们可以实现Action接口来创建我们的动作类。这个接口有一个我们需要实现的方法execute()。使用此接口的唯一好处是它包含一些我们可以用于结果页面的常量,这些常量是SUCCESS,ERROR,NONE,INPUT和LOGIN。

ActionSupport类是Action接口的默认实现,它还实现了与Validation和i18n支持相关的接口。ActionSupport类实现Action,Validateable,ValidationAware,TextProvider和LocaleProvider接口。我们可以覆盖ActionSupport类的validate()方法,以在我们的操作类中包含字段级验证登录。

根据需求,我们可以使用任何方法来创建struts 2动作类,我最喜欢的是ActionSupport类,因为它有助于在动作类中轻松编写验证和i18n逻辑。

 

16.我们怎样才能在动作类中获得Servlet API请求,响应,HttpSession等对象?

Struts2操作类不提供对Servlet API组件的直接访问,例如Request,Response和Session。但是,有时我们需要在操作类中进行这些访问,例如检查HTTP方法或设置响应中的cookie。

这就是为什么Struts2 API提供了一堆* Aware接口,我们可以实现这些接口来访问这些对象。Struts2 API使用依赖注入在操作类中注入Servlet API组件。一些重要的Aware接口是SessionAware,ApplicationAware,ServletRequestAware和ServletResponseAware。

 

17.execAndWait拦截器有什么用?

Struts2为长时间运行的动作类提供了execAndWait拦截器。我们可以使用此拦截器将中间响应页面返回给客户端,一旦处理完成,最终响应将返回给客户端。此拦截器在struts-default包中定义,实现在ExecuteAndWaitInterceptor类中。

 

18.Struts2中令牌拦截器的用途是什么?

Web应用程序的主要问题之一是双表单提交。如果不注意,双重表单提交可能会导致向客户收取双倍金额或两次更新数据库值。我们可以使用令牌拦截器来解决双表格提交问题。这个拦截器是在struts-default包中定义的,但它不是任何拦截器堆栈的一部分,所以我们需要在我们的动作类中手动包含它。

 

19.我们如何在Struts2应用程序中集成log4j?

Struts2提供了log4j API的简单集成以便进行日志记录,我们需要的只是WEB-INF / classes目录中的log4j配置文件。

 

20.什么是不同的Struts2标签?我们怎样才能使用它们?

Struts2提供了许多自定义标记,我们可以在结果页面中使用它们来创建客户端请求的视图。这些标签大致分为三类 - 数据标签,控制标签和UI标签。

我们可以通过使用taglib指令在JSP页面中添加这些标记来使用这些标记。

<%@ taglib uri="/struts-tags" prefix="s" %>

一些重要的Data标签是property,set,push,bean,action,include,i18n和text标签。

控制标签用于处理和导航集合中的数据。一些重要的Control标签是if-elseif-else,iterator,append,merge,sort,subset和generator标签。

Struts2 UI标签用于生成HTML标记语言,将HTML表单数据绑定到动作类属性,类型转换,验证和i18n支持。一些重要的UI标签是form,textfield,password,textarea,checkbox,select,radio和submit标签。

 

21.什么是Struts2中的自定义类型转换器?

Struts2支持OGNL表达式语言,它在Struts 2中执行两项重要任务 - 数据传输和类型转换。

OGNL非常灵活,我们可以轻松扩展它以创建我们自己的自定义转换器类。创建和配置自定义类型转换器类非常简单,第一步是修复自定义类的输入格式。第二步是实现转换器类。类型转换器类应该实现com.opensymphony.xwork2.conversion.TypeConverter接口。由于在Web应用程序中,我们总是以String的形式获取请求并以String的形式发送响应,Struts 2 API提供了TypeConverter接口的默认实现,即StrutsTypeConverter。StrutsTypeConverter包含两个抽象方法 - convertFromString将String转换为Object,convertToString将Object转换为String。

 

22.我们如何编写自己的拦截器并将其映射为动作?

我们可以实现com.opensymphony.xwork2.interceptor.Interceptor接口来创建自己的拦截器。一旦拦截器类准备就绪,我们需要在我们想要使用它的struts.xml包中定义它。我们还可以使用自定义拦截器和defaultStack拦截器创建拦截器堆栈。之后我们可以为我们想要使用拦截器的动作类配置它。

 

23.什么是拦截器的生命周期?

拦截器接口定义了三个方法 - init(),destroy()和intercept()。init和destroy是拦截器的生命周期方法。拦截器是Singleton类,Struts2初始化一个新线程来处理每个请求。创建拦截器实例时调用init()方法,我们可以初始化此方法中的任何资源。应用程序关闭时调用destroy()方法,我们可以释放此方法中的任何资源。

intercept()是每次客户端请求通过拦截器时调用的方法。

 

24.什么是拦截器堆栈?

拦截器堆栈可帮助我们将多个拦截器组合在一起以供进一步使用。struts-default包创建了一些最常用的拦截器堆栈--basicStack和defaultStack。我们可以在包的开头创建我们自己的拦截器堆栈,然后配置我们的动作类来使用它。

 

25.什么是struts-default包,它有什么好处?

struts-default是一个抽象包,它定义了所有Struts2拦截器和常用的拦截器堆栈。建议在配置应用程序包时扩展此程序包,以避免再次配置拦截器。这是为了帮助开发人员消除在我们的应用程序中配置拦截器和结果页面的繁琐任务。

 

26.Struts2操作URI的默认后缀是什么?我们如何更改它?

Struts2操作的默认URI后缀是.action,在Struts1中,默认后缀为.do。我们可以通过在Struts2配置文件中定义struts.action.extension常量值来更改此后缀:

<constant name="struts.action.extension" value="action,do"></constant>

 

27.结果页面的默认位置是什么?我们如何更改它?

默认情况下,Struts2在{WEBAPP-ROOT} / {Namespace} /目录中查找结果页面,但有时我们希望将结果页面保存在另一个位置,我们可以在Struts2配置文件中提供struts.convention.result.path常量值来更改结果页面位置。

另一种方法是在操作类中使用@ResultPath批注来提供结果页面位置。

 

28.我们如何在Struts2应用程序中上传文件?

文件上载是Web应用程序中的常见任务之一。这就是为什么Struts2通过FileUploadInterceptor提供对文件上传的内置支持。此拦截器在struts-default包中配置,并提供选项以设置文件的最大大小和可以上载到服务器的文件类型。

 

29.开发Struts2应用程序时要遵循哪些最佳实践?

开发Struts2应用程序时的一些最佳实践是:

  1. 在创建程序包时始终尝试扩展struts-default程序包,以避免在配置拦截器时出现代码冗余。

  2. 对于整个应用程序中的常见任务,例如记录请求参数,请尝试使用拦截器。

  3. 始终将动作类java bean属性保存在单独的bean中以便重用代码并实现ModelDriven接口。

  4. 如果您有将在多个操作中使用的自定义拦截器,请为此创建拦截器堆栈,然后使用它。

  5. 尝试使用基于功能区域的命名空间配置在不同模块中划分应用程序。

  6. 尝试在结果页面中使用Struts2标记进行代码说明,如果需要,可以创建自己的类型转换器。

  7. 使用开发模式可以加快开发速度,但请确保生产代码不以dev模式运行。

  8. 使用Struts2 i18n支持资源包并支持本地化。

  9. Struts2提供了许多可以拥有资源包的地方,但是尝试保留一个全局资源包,一个用于动作类以避免混淆。

  10. struts-default包配置所有拦截器并创建不同的拦截器堆栈。尝试仅使用所需的内容,例如,如果您没有本地化要求,则可以避免使用i18n拦截器。

 

30.如何处理Struts2中应用程序抛出的异常?

Struts2为异常处理提供了一个非常强大的框架。我们可以在包中指定全局结果,然后将特定的例外映射到这些结果页面。异常映射可以在全局包级别和操作级别完成。

当发生一些未由应用程序处理的意外异常时,让异常结果页面向用户提供一些信息是个好主意。struts.xml文件中的示例配置如下所示。

<package name="user" namespace="/" extends="struts-default"><global-results><result name="exception">/exception.jsp</result><result name="runtime_exception">/runtime_exception.jsp</result><result name="error">/error.jsp</result>
</global-results><global-exception-mappings><exception-mapping exception="java.lang.Exception" result="exception"></exception-mapping><exception-mapping exception="java.lang.Error" result="error"></exception-mapping><exception-mapping exception="java.lang.RuntimeException" result="runtime_exception"></exception-mapping>
</global-exception-mappings><action name="myaction" class="com.journaldev.struts2.exception.MyAction"></action><action name="myspecialaction" class="com.journaldev.struts2.exception.MySpecialAction"><exception-mapping exception="java.io.IOException" result="login"></exception-mapping><result name="login">/error.jsp</result></action>
</package>

 


http://chatgpt.dhexx.cn/article/qo63O0MS.shtml

相关文章

查看es的tcp和http端口

1、登录linux部署服务器&#xff0c;用命令查找配置文件elasticsearch.yml&#xff0c;如图 find -name elasticsearch.yml 2、进到elasticsearch.yml文件的目录 3、查看tcp&#xff0c;http端口

w10查看端口_Windows 10系统如何查看已打开的端口

最近Win10用户反映&#xff0c;电脑很经常中病毒&#xff0c;用户表示并没有在电脑上插入U盘&#xff0c;也没有打开不安全的网页&#xff0c;但就是一直中毒&#xff0c;这让用户非常苦恼。其实&#xff0c;出现这一问题&#xff0c;可能与电脑开启了一些端口有关&#xff0c;…

使用frp端口映射实现内网穿透(SSH、HTTP服务)

使用frp端口映射实现内网穿透(SSH、HTTP服务) 一、下载 通过内网穿透的原理和实现方式的学习我们已经明白了内网穿透的原理&#xff0c;想要实现内网穿透就需要让内网实现与具有公网IP的设备进行绑定。 我们这里使用frp&#xff08;一个专注于内网穿透的高性能的反向代理应用…

rinetd端口转发工具

前言 环境&#xff1a;Centos7.9 rinetd.tar.gz 在生产环境中&#xff0c;为了网络安全&#xff0c;我们需要进行端口转发&#xff0c;而rinetd是一款很好用的端口转发工具&#xff0c;下面我们就来讲解一下如何使用rinetd来实现端口转发。rinetd的下载地址&#xff1a;http:…

电脑端口详解

计算机端口号总数&#xff1a;65535&#xff0c;一般用到的是1~65535&#xff0c;0一般不使用 0-1023&#xff1a; 系统端口&#xff0c;也叫公认端口&#xff0c;这些端口只有系统特许的进程才能使用&#xff1b;1024~65535为用户端口&#xff1a; 1024-5000&#xff1a; 临时…

HTTP服务占用80端口的解决办法,找出占用80的元凶。

电脑没有运行web服务&#xff0c;但是80端口被占用&#xff0c;导致运行使用80端口的软件的时候提示80端口监听失败。 网络上搜索一般给的办法是 net stop HTTP&#xff0c;把windows的http API禁用&#xff0c;这样确实80端口没有占用了&#xff0c;但是所有依赖http的服务就…

python端口扫描

文章目录 python网络编程socket函数服务器端套接字函数客户端套接字函数公共用途套接字 C/S架构实践 编写端口扫描器多线程端口扫描2.0 python网络编程 socket又称“套接字”&#xff0c;应用程序通常通过“套接字”向网络发出请求或者应答请求。使主机间或者一台计算机上的进…

https默认端口443_为什么选择80作为默认HTTP端口,选择443作为默认HTTPS端口?

https默认端口443 While many of us are familiar with various ports being assigned for specific purposes or uses, we may not know the particular reason why they were chosen. Today’s SuperUser Q&A post has the answers to a curious reader’s questions. 尽…

HTTP协议

目录 前置 1.网络划分 1&#xff09;局域网 2&#xff09;广域网 2.IP地址和端口号 1&#xff09;IP地址 2&#xff09;端口号 3.网络通信 一&#xff0c;概念 1.HTTP 2.二进制数据和文本 二&#xff0c;抓包 1.网络抓包 2.URL&#xff08;统一资源定位器&#…

C语言字符串数组赋值错误

直接上代码&#xff1a; #include"stdio.h"int main(){char a[10];for(int i 0; i<10;i){printf("第%d个&#xff1a;",i);scanf("%c",&a[i]);}return 0; }经典的错误&#xff0c;标准的零分&#xff01; 这样的赋值手法&#xff0c;是…

c 语言定义2维字符串数组赋值,二维数组赋值字符串 c 语言 二维字符串数组赋值问题...

C语言中二维字符数组应该怎样赋值&#xff1f; c语言二维数组如何定义字符串&#xff1f;&#xff1f;&#xff1f;&#xff1f;急。。。 二维字符数组的定义格式为&#xff1a;char 数组名[第一维大小][第二维大小]; 例如&#xff1a;char c[3][10]; //定义了一个3行10列的二维…

关于中字符串常量给字符数组赋值

结论 在定义字符数组时&#xff0c;可以同时初始化字符数组&#xff0c;即用字符串常量给字符数组赋值在定义完之后&#xff0c;则不允许用字符串常量给字符数组赋值。如需赋值&#xff0c;则使用strcpy()函数&#xff08;需包含头文件string.h&#xff09; #include <std…

C语言:字符数组赋值

字符数组&#xff1a;C语言学习中较麻烦的部分&#xff0c;C语言中没有字符串这种类型的数组&#xff0c;字符串只能存储在字符型数组中。 1、定义时直接赋值 char a[10]{"I LOVE C"};//可以直接省去花括号直接写成char a[10]I LOVE C"; 注意&#xff1a;此处的…

【C#】 Convert.ToInt16 、Convert.ToInt32、Convert.ToInt64 区别

一般写程序是用的都是Convert.ToInt32&#xff0c;为什么呢&#xff1f; 1.Convert.ToInt是数据类型转换成int类型 2. 有三种方法toint16,toint32,toint64 int16-数值范围&#xff1a;-32768 到 32767 int32-数值范围&#xff1a;-2,147,483,648 到 2,147,483,647 …

C# 中int short Int16 Int32 Int64详解

Java中没有Int32,Int64,,只有int,short,long Java中int就代表Int32 ,short就代表Int16&#xff0c;long就代表Int64 首先&#xff0c;几个基本的关键字&#xff1a; Int16 short, 占2个字节. -32768 ~ 32767 Int32 int, 占4个字节. -2147483648 ~ 2147483647 Int64 lon…

【C++】INT32_MAX

INT32_MAX INT32_MAX可以把它认为在limits.h下面的一个宏。关于宏&#xff0c;可以参考这篇文章&#xff0c;直接点击&#xff01;其实就是一个别称&#xff01;

python中int的取值范围_int32的取值范围是多少?

int32的数值取值范围为“-2147483648”到“2147483647”;而int64的数值取值范围为“-9223372036854775808”到“9223372036854775808”。 int32的取值范围 计算机中32位int类型变量的范围,其中int类型是带符号整数。 正数在计算机中表示为原码,最高位为符号位: 1的原码为000…

c语言unsigned int 范围,unsigned int 32比特数据范围为-2147

提到unsigned,大家应该都了解,有朋友问c语言中unsigned什么意思,还有人想问c语言中的unsigned是什么意思,这到底是咋回事?事实上unsigned呢,下面是小编推荐给大家的unsigned int,下面我们一起来看看吧! unsigned int 一、指代不同 1、int:定义整数类型变量的标识符。 …

C#中ToInt32以及类似函数用法介绍

C#中ToInt32以及类似函数用法介绍 作用程序举例程序逻辑程序代码 程序 作用 将指定的值转换为 32 位有符号整数。对应的还有ToInt16&#xff0c;ToInt64 指定的值可以是字符串、时间、位等数据类型。 程序举例 程序逻辑 当输入值整数时&#xff0c;当输入值大于0&#xff0…

C语言 —— int32_t uint32_t 及size_t

文章目录 int32_t和int区别使用原因stdint.h源码 int32_t和uint32_t的区别size_t在不同机器中定义不同&#xff1a;stdint.h源码 参考文档 int32_t和int区别 我们都知道&#xff0c;C语言的基本类型就char, short, int 等。但是我们在看其他源码时经常碰到int32_t, int8_t这种…