❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注、点赞、收藏、评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉
文章目录
- 1、说一说Servlet的生命周期?
- 2、request.getAttribute()和 request.getParameter()有何区别?
- 3、MVC的各个部分都有那些技术来实现?如何实现?
- 4、jsp有哪些内置对象?作用分别是什么?
- 5、session 和 cookie 有什么区别?
- 6、jsp 和 servlet 有什么区别?
- 7、如何避免sql注入?
- 8、JDBC访问数据库的基本步骤是什么?
- 9、说说preparedStatement和Statement的区别?
- 10、数据库连接池的原理,为什么要使用连接池?
- 11、JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?
- 12、JDBC的DriverManager是用来做什么的?
- 13、AJAX有哪些优点和缺点?
- 14、什么是JDBC?
- 15、原生 JDBC操作数据库流程?
- 16、常见的JDBC异常有哪些?
- 17、JDBC的DataSource是什么,有什么好处?
- 18、RowSet和ResultSet的区别?
- 19、HTTP中重定向和请求转发的区别?
- 20、如何利用实现自动功能?
- 21、Cookie的过期和Session的超时有什么区别?
- 22、如何解决分布式Session问题?
- 23、在单点登录中,如果 cookie 被禁用了怎么办?
- 24、session何时被删除?
- 25、什么是过滤器?
- 26、什么是监听器?
- 27、什么是拦截器?
- 28、过滤器和拦截器的区别?
- 29、Servlet与Filter的区别?
- 30、web.xml 的作用?
- 31、filter的生命周期?
- 32、谈谈你对 MVC 模式的理解?
- 33、SpringMVC 的核心组件有哪些?
- 34、SpringMVC 常用的注解有哪些?
- 35、@RequestMapping 的作用是什么?
- 36、如何解决 POST 请求中文乱码问题,GET 的又如何处理呢?
- 37、SpringMVC 的控制器是不是单例模式,如果是会有什么问题,怎么解决?
- 38、SpringMVC 怎么样设定重定向和转发的?
- 39、SpringMVC 里面拦截器是怎么写的?
- 40、SpringMVC 和 Struts2 的区别有哪些?
1、说一说Servlet的生命周期?
Servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init(),service()和destroy方法表达。
Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do()方法。结束服务,web容器调用servlet的destroy()方法。
2、request.getAttribute()和 request.getParameter()有何区别?
- request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据。request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
- getAttribute是返回对象,getParameter返回字符串。
- getAttribute()一向是和setAttribute()一起使用的,只有先用setAttribute()设置之后,才能够通过getAttribute()来获得值,它们传递的是Object类型的数据。而且必须在同一个request对象中使用才有效。而getParameter()是接收表单的get或者post提交过来的参数。
3、MVC的各个部分都有那些技术来实现?如何实现?
MVC是Model-View-Controller的简写。Model代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),View是应用的表示面(由JSP页面产生),Controller是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
4、jsp有哪些内置对象?作用分别是什么?
JSP有9个内置对象:
- request:封装客户端的请求,其中包含来自GET或POST请求的参数;
- response:封装服务器对客户端的响应;
- pageContext:通过该对象可以获取其他对象;
- session:封装用户会话的对象;
- application:封装服务器运行环境的对象;
- out:输出服务器响应的输出流对象;
- config:Web应用的配置对象;
- page:JSP页面本身(相当于Java程序中的this);
- exception:封装页面抛出异常的对象
5、session 和 cookie 有什么区别?
- 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。
- 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
- Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。所以,总结一下:Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
6、jsp 和 servlet 有什么区别?
- jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类);
- jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。
- Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到。
- Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。
7、如何避免sql注入?
- PreparedStatement(简单又有效的办法)
- 使用正则表达式过滤传入的参数
- 字符串过滤
- JSP中调用该函数检查是否包含非法字符
- JSP页面判断代码
8、JDBC访问数据库的基本步骤是什么?
- 加载驱动;
- 通过DriverManager对象获取连接对象Connection;
- 通过连接对象获取会话;
- 通过会话进行数据的增删改查,封装对象;
- 关闭资源。
9、说说preparedStatement和Statement的区别?
-
效率:预编译会话比普通会话对象,数据库系统不会对相同的sql语句不会再次编译。
-
安全性:可以有效的避免sql注入攻击!sql注入攻击就是从客户端输入一些非法的特殊字符,而使服务器端在构造sql语句的时候仍然能够正确构造,从而收集程序和服务器的信息和数据。
比如:
“select * from t_user where userName = ‘” + userName + “ ’ and password =’” + password + “’”
如果用户名和密码输入的是<code>’1’ or ‘1’=’1’</code>
; 则生产的sql语句是:
“select * from t_user where userName = ‘1’ or ‘1’ =’1’ and password =’1’ or ‘1’=’1’
这个语句中的where 部分没有起到对数据筛选的作用。
10、数据库连接池的原理,为什么要使用连接池?
-
数据库连接是一件费时的操作,连接池可以使多个操作共享一个连接。
-
数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量、使用情况,为系统开发,测试及性能调整提供依据。
-
使用连接池是为了提高对数据库连接资源的管理。
11、JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?
当我们使用事务时,有可能会出现这样的情况,有一行数据刚更新,与此同时另一个查询读到了这个刚更新的值。
这样就导致了脏读,因为更新的数据还没有进行持久化,更新这行数据的业务可能会进行回滚,这样这个数据就是无效的。
数据库的TRANSACTIONREADCOMMITTED,TRANSACTIONREPEATABLEREAD,和TRANSACTION_SERIALIZABLE隔离级别可以防止脏读。
12、JDBC的DriverManager是用来做什么的?
JDBC的DriverManager是一个工厂类,我们通过它来创建数据库连接。当JDBC的Driver类被加载进来时,它会自己注册到DriverManager类里面,然后我们会把数据库配置信息传成DriverManager.getConnection()方法,DriverManager会使用注册到它里面的驱动来获取数据库连接,并返回给调用的程序。
13、AJAX有哪些优点和缺点?
优点:
- 最大的一点是页面无刷新,用户的体验非常好。
- 使用异步方式与服务器通信,具有更加迅速的响应能力。
- 可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
- 基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
缺点:
- ajax不支持浏览器back按钮;
- 安全问题ajax暴露了与服务器交互的细节;
- 对搜索引擎的支持比较弱;
- 破坏了程序的异常机制;
- 不容易调试。
14、什么是JDBC?
JDBC的全程是 Java Database connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。 JDBC接口及相关类在java.sql包和javax.sql包里。 我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。
15、原生 JDBC操作数据库流程?
Class.forName()
加载数据库连接驱动;DriverManager.getConnection()
获取数据库连接对象;- 根据 SQL 获取 sql 会话对象,有 2 种方式 Statement、PreparedStatement ;
- 执行 SQL 处理结果集,执行 SQL 前如果有参数值就设置参数值 setXXX();
- 关闭结果集、关闭会话、关闭连接。
16、常见的JDBC异常有哪些?
java.sql.SQLException
:JDBC异常的基类。java.sql.BatchUpdateException
:当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException中。java.sql.SQLWarning
SQL操作出现的警告信息。java.sql.DataTruncation
字段值由于某些非正常原因被拦截了。
17、JDBC的DataSource是什么,有什么好处?
DataSource即数据源,它是定义在javax.sql中的一个接口,跟DriverManager相比,它的功能要更强大。我们可以用它来创建数据库连接,当然驱动的实现类会实际去完成这个工作。除了能创建连接外,它还提供了如下的特性:
- 缓存PreparedStatement以便更快的执行
- 可以设置连接超时时间
- 提供日志记录的功能
- ResultSet大小的最大阈值设置
- 通过JNDI的支持,可以为servlet容器提供连接池的功能
18、RowSet和ResultSet的区别?
RowSet继承自ResultSet,因此它有ResultSet的全部功能,同时它自己添加了些额外的特性。 RowSet一个最大的好处是它可以是离线的,这样使得它更轻量级,同时便于在网络间进行传输。
19、HTTP中重定向和请求转发的区别?
本质区别:
- 转发是服务端行为
- 重定向是客户端行为
重定向特点:两次请求,浏览器地址发生改变,可以访问自己web之外的资源,传输的数据会丢失。
请求转发特点: 一次强求,浏览器地址不变,访问的是自己本身的web资源,传输的数据不会丢失。
20、如何利用实现自动功能?
当用户在某个网站注册后,就会收到一个唯一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户无需给出明确的用户名和密码,就可以访问服务器上的资源。
21、Cookie的过期和Session的超时有什么区别?
Cookie的过期和Session的超时(过期),都是对某个对象设置一个时间,然后采用轮训机制(或者首次访问时)检查当前对象是否超时(当前对象会保存一个开始时间),如果超时则进行移除。 cookie保存在浏览器中,不安全。而session是保存在服务端的。cookie的生命周期很长,而session很短,一般也就几十分钟。
cookie是保存在客户端,session保存在服务器端,cookie保存着session相关信息。 如果cookie没有超时,那么浏览器每次请求都会带上该cookie信息,服务器端根据cookie信息从session缓存中获取相对应的session。这两个信息有一个超时,用户连接即宣告关闭。
会话的超时由服务器来维护,它不同于Cookie的失效日期。 首先,会话一般基于驻留内存的cookie,不是持续性的cookie,因而也就没有截至日期。 即使截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。
22、如何解决分布式Session问题?
Nginx ip_hash策略
,服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。Session 复制
,任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。共享 Session
,服务端无状态话,将用户的 Session 等信息使用缓存中间件来统一管理,保障分发到每一个服务器的响应结果都一致。
23、在单点登录中,如果 cookie 被禁用了怎么办?
单点登录的原理是后端生成一个 session ID,然后设置到cookie,后面的所有请求浏览器都会带上 cookie,然后服务端从 cookie 里获取 session ID,再查询到用户信息。 所以,保持登录的关键不是 cookie,而是通过cookie 保存和传输的 session ID,其本质是能获取用户信息的数据。 除了 cookie,还通常使用 HTTP 请求头来传输。但是这个请求头浏览器不会像 cookie 一样自动携带,需要手工处理。
24、session何时被删除?
session在下列情况下被删除:
- 程序调用
HttpSession.invalidate()
; - 距离上一次收到客户端发送的session id时间间隔超过了 session的最大有效时间;
- 服务器进程被停止。
注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
25、什么是过滤器?
定义 : 依赖于servlet容器,在实现上 基于函数回调
,可以对几乎所有请求进行过滤;缺点是一个过滤器实例只能在容器初始化时调用一次;
作用 : 用来做一些过滤操作,获取我们想要获取的数据: 在过滤器中修改字符编码; 在过滤器中修改HttpServletRequest
的一些参数,包括:过滤低俗文字、危险字符等。
26、什么是监听器?
定义 : 实现了javax.servlet.ServletContextListener
接口的服务器端程序; 随web应用的启动而启动;只初始化一次; 随web应用的停止而销毁;
作用 : 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。如springmvc的监听器org.springframework.web.context.ContextLoaderListener
,实现了SpringMVC容器的加载、Bean对象创建、DispatchServlet初始化等。
27、什么是拦截器?
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架; 在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用; 缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理;
由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。
28、过滤器和拦截器的区别?
拦截器 | 过滤器 |
---|---|
基于Jaba反射机制 | 基于函数回调 |
不依赖Servlet容器 | 依赖Servlet容器 |
只能对action起作用 | 几乎对所有请求起作用 |
在Action生命周期中,拦截器可以多次被调用 | 过滤器只能在容器初始化时被调用一次 |
拦截器不能修改request | 过滤器可以修改request |
拦截器可以调用IOC容器中的各种依赖 | 过滤器不能调用IOC容器中的各种依赖 |
拦截器可以详细到每个方法 | 过滤器只能在请求的前后使用 |
过滤器主要是过滤出要的东西,如requeset中的信息;拦截器在做安全方面用的比较多,比如终止一些流程
29、Servlet与Filter的区别?
Filter是一种特别的Servlet,它们的作用是完全不一样的。 Servlet是用来处理请求的,而Filter是用来过滤检查请求的。
30、web.xml 的作用?
用于配置Web应用的相关信息 如:监听器(listener)、过滤器(filter)、 Servlet、相关参数、会话超时时间、安全验证方式、错误页面等。
31、filter的生命周期?
- 启动服务器加载过滤器的实例,并调用
init()
方法来初始化实例; - 每一次请求时都只调用方法
doFilter()
进行处理; - 停止服务器时调用
destroy()
方法,销毁实例。
需要实现javax.servlet包的Filter接口的三方法init()、doFilter()、destroy()
32、谈谈你对 MVC 模式的理解?
MVC 是 Model — View — Controler 的简称,它是一种架构模式,它分离了表现与交互。它被分为三个核心部件:模型、视图、控制器。
Model(模型):是程序的主体部分,主要包含业务数据和业务逻辑。在模型层,还会涉及到用户发布的服务,在服务中会根据不同的业务需求,更新业务模型中的数据。
View(视图):是程序呈现给用户的部分,是用户和程序交互的接口,用户会根据具体的业务需求,在 View 视图层输入自己特定的业务数据,并通过界面的事件交互,将对应的输入参数提交给后台控制器进行处理。
Controller(控制器):Controller 是用来处理用户输入数据,以及更新业务模型的部分。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。
33、SpringMVC 的核心组件有哪些?
1. 前端控制器 DispatcherServlet
作用:Spring MVC 的入口函数。接收请求,响应结果,相当于转发器,中央处理器。有了 DispatcherServlet 减少了其它组件之间的耦合度。用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
2. 处理器映射器 HandlerMapping
作用:根据请求的 url 查找 Handler。HandlerMapping 负责根据用户请求找到 Handler 即处理器(Controller),SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3. 处理器适配器 HandlerAdapter
作用:按照特定规则(HandlerAdapter 要求的规则)去执行 Handler。通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
4. 处理器 Handler
注意:编写 Handler 时按照 HandlerAdapter 的要求去做,这样适配器才可以去正确执行 Handler。Handler 是继 DispatcherServlet 前端控制器的后端控制器,在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理。由于 Handler 涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发 Handler。
5. 视图解析器 View resolver
作用:进行视图解析,根据逻辑视图名解析成真正的视图(View )。View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。SpringMVC 框架提供了很多的 View 视图类型,包括:jstlView、freemarkerView、pdfView 等。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面。
6. 视图 View
View 是一个接口,实现类支持不同的 View 类型(jsp、freemarker…)。
34、SpringMVC 常用的注解有哪些?
- @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径;
- @RequestBody:注解实现接收 HTTP 请求的 json 数据,将 json 转换为 Java 对象;
- @ResponseBody:注解实现将 Controller 方法返回对象转化为 json 对象响应给客户。
35、@RequestMapping 的作用是什么?
RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。RequestMapping 注解有六个属性,下面我们把它分成三类进行说明。
value、method:
- value:指定请求的实际地址,指定的地址可以是 URI Template 模式;
- method:指定请求的method类型, GET、POST、PUT、DELETE 等;
consumes、produces:
- consumes:指定处理请求的提交内容类型(Content-Type),例如 application/json、text/html;
- produces:指定返回的内容类型,仅当 request 请求头中的(Accept)类型中包含该指定类型才返回;
params、header:
- params:指定 request 中必须包含某些参数值是,才让该方法处理。
- headers:指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求。
36、如何解决 POST 请求中文乱码问题,GET 的又如何处理呢?
-
解决 POST 请求乱码问题:在 web.xml 中配置一个 CharacterEncodingFilter 过滤器,设置成 utf-8;
-
GET 请求中文参数出现乱码解决方法有两个:
(1)修改tomacat 配置文件添加编码与工程编码一致,如下:
ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort
(2)对参数进行重编码
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
37、SpringMVC 的控制器是不是单例模式,如果是会有什么问题,怎么解决?
是单例模式,所以在多线程访问的时候有线程安全问题。但是不要使用同步,会影响性能,解决方案是在控制器里面不能写字段。
38、SpringMVC 怎么样设定重定向和转发的?
-
转发:在返回值前面加 “forward:”,譬如:
"forward:user.do?name=method2"
-
重定向:在返回值前面加 “redirect:”
39、SpringMVC 里面拦截器是怎么写的?
方法一:实现 HandlerInterceptor 接口;
方法二:继承适配器类,接着在接口方法当中,实现处理逻辑,然后在 SpringMVC 的配置文件中配置拦截器即可。
40、SpringMVC 和 Struts2 的区别有哪些?
- SpringMVC 的入口是一个 Servlet 即前端控制器(DispatchServlet),而 Struts2 入口是一个 filter 过虑器(StrutsPrepareAndExecuteFilter);
- SpringMVC 是基于方法开发(一个 url 对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),Struts2 是基于类开发,传递参数是通过类的属性,只能设计为多例;
- Struts2 采用值栈存储请求和响应的数据,通过 OGNL 存取数据;SpringMVC 通过参数解析器是将 request 请求内容解析,并给方法形参赋值,将数据和视图封装成 ModelAndView 对象,最后又将 ModelAndView 中的模型数据通过 request 域传输到页面。jsp 视图解析器默认使用 jstl。
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 分享👥 留言💬thanks!!!