三天吃透 SpringMVC 面试八股文
本文已经收录到 Github 仓库,该仓库包含计算机基础、Java 基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎 star~
Github 地址:https://github.com/Tyson0314/Java-learning
说说你对 SpringMVC 的理解
SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 Spring 框架的一个模块。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。
什么是 MVC 模式?
MVC 的全名是Model View Controller
,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码,将众多的业务逻辑聚集到一个部件里面,在需要改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,达到减少编码的时间。
View,视图是指用户看到并与之交互的界面。比如由 html 元素组成的网页界面,或者软件的客户端界面。MVC 的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。
model,模型是指模型表示业务规则。在 MVC 的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
controller,控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
SpringMVC 有哪些优点?
与 Spring 集成使用非常方便,生态好。
配置简单,快速上手。
支持 RESTful 风格。
支持各种视图技术,支持各种请求资源映射策略。
Spring MVC 和 Struts 的区别
Spring MVC 是基于方法开发,Struts2 是基于类开发的。
Spring MVC 会将用户请求的 URL 路径信息与 Controller 的某个方法进行映射,所有请求参数会注入到对应方法的形参上,生成 Handler 对象,对象中只有一个方法;
Struts 每处理一次请求都会实例一个 Action,Action 类的所有方法使用的请求参数都是 Action 类中的成员变量,随着方法增多,整个 Action 也会变得混乱。
Spring MVC 支持单例开发模式,Struts 只能使用多例
Struts 由于只能通过类的成员变量接收参数,故只能使用多例。
Struts2 的核心是基于一个 Filter 即 StrutsPreparedAndExcuteFilter,Spring MVC 的核心是基于一个 Servlet 即 DispatcherServlet(前端控制器)。
Struts 处理速度稍微比 Spring MVC 慢,Struts 使用了 Struts 标签,加载数据较慢。
Spring MVC 的工作原理
Spring MVC 的工作原理如下:
DispatcherServlet 接收用户的请求
找到用于处理 request 的 handler 和 Interceptors,构造成 HandlerExecutionChain 执行链
找到 handler 相对应的 HandlerAdapter
执行所有注册拦截器的 preHandler 方法
调用 HandlerAdapter 的 handle() 方法处理请求,返回 ModelAndView
倒序执行所有注册拦截器的 postHandler 方法
请求视图解析和视图渲染
Spring MVC 的主要组件?
前端控制器(DispatcherServlet):接收用户请求,给用户返回结果。
处理器映射器(HandlerMapping):根据请求的 url 路径,通过注解或者 xml 配置,寻找匹配的 Handler。
处理器适配器(HandlerAdapter):Handler 的适配器,调用 handler 的方法处理请求。
处理器(Handler):执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装到 ModelAndView 对象中。
视图解析器(ViewResolver):将逻辑视图名解析成真正的视图 View。
视图(View):接口类,实现类可支持不同的 View 类型(JSP、FreeMarker、Excel 等)。
Spring MVC 的常用注解由有哪些?
@Controller:用于标识此类的实例是一个控制器。
@RequestMapping:映射 Web 请求(访问路径和参数)。
@ResponseBody:注解返回数据而不是返回页面
@RequestBody:注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。
@PathVariable:获得 URL 中路径变量中的值
@RestController:@Controller+@ResponseBody
@ExceptionHandler 标识一个方法为全局异常处理的方法。
@Controller 注解有什么用?
@Controller
注解标记一个类为 Spring Web MVC 控制器。Spring MVC 会将扫描到该注解的类,然后扫描这个类下面带有 @RequestMapping
注解的方法,根据注解信息,为这个方法生成一个对应的处理器对象,在上面的 HandlerMapping 和 HandlerAdapter 组件中讲到过。
当然,除了添加 @Controller
注解这种方式以外,你还可以实现 Spring MVC 提供的 Controller
或者 HttpRequestHandler
接口,对应的实现类也会被作为一个处理器对象
本文已经收录到 Github 仓库,该仓库包含计算机基础、Java 基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎 star~
Github 地址:https://github.com/Tyson0314/Java-learning
@RequestMapping 注解有什么用?
@RequestMapping
注解,用于配置处理器的 HTTP 请求方法,URI 等信息,这样才能将请求和方法进行映射。这个注解可以作用于类上面,也可以作用于方法上面,在类上面一般是配置这个控制器的 URI 前缀。
@RestController 和 @Controller 有什么区别?
@RestController
注解,在 @Controller
基础上,增加了 @ResponseBody
注解,更加适合目前前后端分离的架构下,提供 Restful API ,返回 JSON 数据格式。
@RequestMapping 和 @GetMapping 注解有什么不同?
@RequestMapping
:可注解在类和方法上;@GetMapping
仅可注册在方法上@RequestMapping
:可进行 GET、POST、PUT、DELETE 等请求方法;@GetMapping
是@RequestMapping
的 GET 请求方法的特例。
@RequestParam 和 @PathVariable 两个注解的区别
两个注解都用于方法参数,获取参数值的方式不同,@RequestParam
注解的参数从请求携带的参数中获取,而 @PathVariable
注解从请求的 URI 中获取
@RequestBody 和 @RequestParam 的区别
@RequestBody 一般处理的是在 ajax 请求中声明 contentType: "application/json; charset=utf-8"时候。也就是 json 数据或者 xml 数据。
@RequestParam 一般就是在 ajax 里面没有声明 contentType 的时候,为默认的x-www-form-urlencoded
格式时。
Spring MVC 的异常处理
可以将异常抛给 Spring 框架,由 Spring 框架来处理;我们只需要配置简单的异常处理器,在异常处理器中添视图页面即可。
使用系统定义好的异常处理器 SimpleMappingExceptionResolver
使用自定义异常处理器
使用异常处理注解
SpringMVC 用什么对象从后台向前台传递数据的?
将数据绑定到 request;
返回 ModelAndView;
通过 ModelMap 对象,可以在这个对象里面调用 put 方法,把对象加到里面,前端就可以通过 el 表达式拿到;
绑定数据到 Session 中。
SpringMvc 的 Controller 是不是单例模式?
单例模式。在多线程访问的时候有线程安全问题,解决方案是在控制器里面不要写可变状态量,如果需要使用这些可变状态,可以使用 ThreadLocal,为每个线程单独生成一份变量副本,独立操作,互不影响。
介绍下 Spring MVC 拦截器?
Spring MVC 拦截器对应 HandlerInterceor 接口,该接口位于 org.springframework.web.servlet 的包中,定义了三个方法,若要实现该接口,就要实现其三个方法:
前置处理(preHandle()方法):该方法在执行控制器方法之前执行。返回值为 Boolean 类型,如果返回 false,表示拦截请求,不再向下执行,如果返回 true,表示放行,程序继续向下执行(如果后面没有其他 Interceptor,就会执行 controller 方法)。所以此方法可对请求进行判断,决定程序是否继续执行,或者进行一些初始化操作及对请求进行预处理。
后置处理(postHandle()方法):该方法在执行控制器方法调用之后,且在返回 ModelAndView 之前执行。由于该方法会在 DispatcherServlet 进行返回视图渲染之前被调用,所以此方法多被用于处理返回的视图,可通过此方法对请求域中的模型和视图做进一步的修改。
已完成处理(afterCompletion()方法):该方法在执行完控制器之后执行,由于是在 Controller 方法执行完毕后执行该方法,所以该方法适合进行一些资源清理,记录日志信息等处理操作。
可以通过拦截器进行权限检验,参数校验,记录日志等操作
SpringMvc 怎么配置拦截器?
有两种写法,一种是实现 HandlerInterceptor 接口,另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在 SpringMvc 的配置文件中配置拦截器即可:
Spring MVC 的拦截器和 Filter 过滤器有什么差别?
有以下几点:
功能相同:拦截器和 Filter 都能实现相应的功能
容器不同:拦截器构建在 Spring MVC 体系中;Filter 构建在 Servlet 容器之上
使用便利性不同:拦截器提供了三个方法,分别在不同的时机执行;过滤器仅提供一个方法
什么是 REST?
REST,英文全称,Resource Representational State Transfer,对资源的访问状态的变化通过 url 的变化表述出来。
Resource:资源。资源是 REST 架构或者说整个网络处理的核心。
Representational:某种表现形式,比如用 JSON,XML,JPEG 等。
State Transfer:状态变化。通过 HTTP method 实现。
REST 描述的是在网络中 client 和 server 的一种交互形式。用大白话来说,就是通过 URL 就知道要什么资源,通过 HTTP method 就知道要干什么,通过 HTTP status code 就知道结果如何。
举个例子:
GET 代表获取一个资源,POST 代表添加一个资源,PUT 代表修改一个资源,DELETE 代表删除一个资源。
server 提供的 RESTful API 中,URL 中只使用名词来指定资源,原则上不使用动词。用HTTP Status Code
传递 server 的状态信息。比如最常用的 200 表示成功,500 表示 Server 内部错误等。
使用 REST 有什么优势呢?
第一,风格统一了,不会出现delUser/deleteUser/removeUser
各种命名的代码了。
第二,面向资源,一目了然,具有自解释性。
第三,充分利用 HTTP 协议本身语义。
最后给大家分享一个 Github 仓库,上面有大彬整理的 300 多本经典的计算机书籍 PDF,包括 C 语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,可以 star 一下,下次找书直接在上面搜索,仓库持续更新中~
Github 地址:https://github.com/Tyson0314/java-books
评论