跳至主要內容

1.Spring MVC 面试题

Java突击队大约 13 分钟

1.Spring MVC 面试题

目录

  • Spring MVC 面试题

  • 简单介绍一下 Spring MVC 框架

  • Spring MVC 有什么优点?

  • 描述一下 Spring MVC 的工作流程

  • 简单介绍 Spring MVC 的核心组件

  • @Controller 注解有什么用?

  • @RequestMapping 注解有什么用?

  • @RestController 和 @Controller 有什么区别?

  • @RequestMapping 和 @GetMapping 注解的不同之处在哪里?

  • @RequestParam 和 @PathVariable 两个注解的区别

  • 返回 JSON 格式使用什么注解?

  • 介绍一下 Spring MVC 中的 WebApplicationContext ?

  • Spring MVC 和 Struts2 的异同?

  • 介绍下 Spring MVC 拦截器?

  • Spring MVC 的拦截器和 Filter 过滤器有什么差别?

  • REST 面试题

  • REST 代表着什么?

  • 资源是什么?

  • 什么是安全的 REST 操作?

  • 什么是幂等操作? 为什么幂等操作如此重要?

  • REST 是可扩展的或说是协同的吗?

  • REST 用哪种 HTTP 方法呢?

  • 删除的 HTTP 状态返回码是什么 ?

  • REST API 是无状态的吗?

  • REST安全吗? 你能做什么来保护它?

简单介绍一下 Spring MVC 框架

在早期Java Web 的开发中,统一把显示层、控制层、显示层的操作全部交给 JSP 或者 Java Bean 来进行处理,存在一定的弊端,例如:JSP 和 Java Bean 之间严重耦合、开发效率低等弊端。

Spring MVC 是 Spring 体系中的一员,提供“模型-视图-控制器”(Model-View-Controller)架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。

MVC模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑和 UI 逻辑,同时在所有这些元素之间提供松散耦合。

Spring MVC 有什么优点?

1、 使用真的非常方便,无论是添加HTTP请求方法映射的方法,还是不同数据格式的响应;
2、 提供拦截器机制,可以方便的对请求进行拦截处理;
3、 提供异常机制,可以方便的对异常做统一处理;
4、 可以任意使用各种视图技术,而不仅仅局限于JSP,例如Freemarker、Thymeleaf等等;

描述一下 Spring MVC 的工作流程

Spring MVC 也是基于 Servlet 来处理请求的,主要通过 DispatcherServlet 这个 Servlet 来处理请求,处理过程需要通过九大组件来完成,先看到下面这个流程图:

 

Spring MVC 处理请求的流程大致如上图所示

1、 用户的浏览器发送一个请求,这个请求经过互联网到达了我们的服务器Servlet容器首先接待了这个请求,并将该请求委托给DispatcherServlet进行处理;
2、 DispatcherServlet将该请求传给了处理器映射组件HandlerMapping,并获取到适合该请求的HandlerExecutionChain拦截器和处理器对象;
3、 在获取到处理器后,DispatcherServlet还不能直接调用处理器的逻辑,需要进行对处理器进行适配处理器适配成功后,DispatcherServlet通过处理器适配器HandlerAdapter调用处理器的逻辑,并获取返回值ModelAndView对象;
4、 之后,DispatcherServlet需要根据ModelAndView解析视图解析视图的工作由ViewResolver完成,若能解析成功,ViewResolver会返回相应的View视图对象;
5、 在获取到具体的View对象后,最后一步要做的事情就是由View渲染视图,并将渲染结果返回给用户;

以上就是 Spring MVC 处理请求的全过程,上面的流程进行了一定的简化,主要涉及到最核心的组件,还有许多其他组件没有表现出来,不过这并不影响大家对主过程的理解。

总结:客户端发起请求后,最终会交由 DispatcherServlet 来处理,它会通过你的 URI 找到对应的方法,从请求中解析参数,然后通过反射机制调用该方法,将方法的执行结果设置到响应中,如果存在对应的 View 对象,则进行页面渲染,实际上就是将请求转发到指定的 URL

简单介绍 Spring MVC 的核心组件

那么接下来就简单介绍一下 DispatcherServlet 和九大组件(按使用顺序排序的):

组件说明
DispatcherServletSpring MVC 的核心组件,是请求的入口,负责协调各个组件工作
MultipartResolver内容类型( Content-Type )为 multipart/* 的请求的解析器,例如解析处理文件上传的请求,便于获取参数信息以及上传的文件
HandlerMapping请求的处理器匹配器,负责为请求找到合适的 HandlerExecutionChain 处理器执行链,包含处理器(handler)和拦截器们(interceptors
HandlerAdapter处理器的适配器。因为处理器 handler 的类型是 Object 类型,需要有一个调用者来实现 handler 是怎么被执行。Spring 中的处理器的实现多变,比如用户处理器可以实现 Controller 接口、HttpRequestHandler 接口,也可以用 @RequestMapping 注解将方法作为一个处理器等,这就导致 Spring MVC 无法直接执行这个处理器。所以这里需要一个处理器适配器,由它去执行处理器
HandlerExceptionResolver处理器异常解析器,将处理器( handler )执行时发生的异常,解析( 转换 )成对应的 ModelAndView 结果
RequestToViewNameTranslator视图名称转换器,用于解析出请求的默认视图名
LocaleResolver本地化(国际化)解析器,提供国际化支持
ThemeResolver主题解析器,提供可设置应用整体样式风格的支持
ViewResolver视图解析器,根据视图名和国际化,获得最终的视图 View 对象
FlashMapManagerFlashMap 管理器,负责重定向时,保存参数至临时存储(默认 Session)

Spring MVC 对各个组件的职责划分的比较清晰。DispatcherServlet 负责协调,其他组件则各自做分内之事,互不干扰。

@Controller 注解有什么用?

@Controller 注解标记一个类为 Spring Web MVC 控制器 Controller。Spring MVC 会将扫描到该注解的类,然后扫描这个类下面带有 @RequestMapping 注解的方法,根据注解信息,为这个方法生成一个对应的处理器对象,在上面的 HandlerMapping 和 HandlerAdapter组件中讲到过。

当然,除了添加 @Controller 注解这种方式以外,你还可以实现 Spring MVC 提供的 Controller 或者 HttpRequestHandler 接口,对应的实现类也会被作为一个处理器对象

@RequestMapping 注解有什么用?

@RequestMapping 注解,在上面已经讲过了,配置处理器的 HTTP 请求方法,URI等信息,这样才能将请求和方法进行映射。这个注解可以作用于类上面,也可以作用于方法上面,在类上面一般是配置这个控制器的 URI 前缀

@RestController 和 @Controller 有什么区别?

@RestController 注解,在 @Controller 基础上,增加了 @ResponseBody 注解,更加适合目前前后端分离的架构下,提供 Restful API ,返回例如 JSON 数据格式。当然,返回什么样的数据格式,根据客户端的 ACCEPT 请求头来决定。

@RequestMapping 和 @GetMapping 注解的不同之处在哪里?

1、 @RequestMapping:可注解在类和方法上;@GetMapping仅可注册在方法上;
2、 @RequestMapping:可进行GET、POST、PUT、DELETE等请求方法;@GetMapping@RequestMapping的GET请求方法的特例,目的是为了提高清晰度;

@RequestParam 和 @PathVariable 两个注解的区别

两个注解都用于方法参数,获取参数值的方式不同,@RequestParam 注解的参数从请求携带的参数中获取,而 @PathVariable 注解从请求的 URI 中获取

返回 JSON 格式使用什么注解?

可以使用 @ResponseBody 注解,或者使用包含 @ResponseBody 注解的 @RestController 注解。

当然,还是需要配合相应的支持 JSON 格式化的 HttpMessageConverter 实现类。例如,Spring MVC 默认使用 MappingJackson2HttpMessageConverter

介绍一下 Spring MVC 中的 WebApplicationContext ?

WebApplicationContext 是实现 ApplicationContext 接口的子类,专门为 WEB 应用准备的

  • 它允许从相对于 Web 根目录的路径中加载配置文件完成初始化 Spring MVC 组件的工作
  • 从 WebApplicationContext 中,可以获取 ServletContext 引用,整个 Web 应用上下文对象将作为属性放置在 ServletContext 中,以便 Web 应用环境可以访问 Spring 上下文。

Spring MVC 和 Struts2 的异同?

入口不同

  • Spring MVC 的入门是一个 Servlet 控制器
  • Struts2 入门是一个 Filter 过滤器

配置映射不同,

  • Spring MVC 是基于方法开发,传递参数是通过方法形参,一般设置为单例
  • Struts2 是基于开发,传递参数是通过类的属性,只能设计为多例

视图不同

  • Spring MVC 通过参数解析器是将 Request 对象内容进行解析成方法形参,将响应数据和页面封装成 ModelAndView 对象,最后又将模型数据通过 Request 对象传输到页面。其中,如果视图使用 JSP 时,默认使用 JSTL
  • Struts2 采用值栈存储请求和响应的数据,通过 OGNL 存取数据。

介绍下 Spring MVC 拦截器?

Spring MVC 拦截器有三个增强处理的地方:

1、 前置处理:在执行方法前执行,全部成功执行才会往下执行方法;
2、 后置处理:在成功执行方法后执行,倒序
3、 已完成处理:不管方法是否成功执行都会执行,不过只会执行前置处理成功的拦截器,倒序

可以通过拦截器进行权限检验,参数校验,记录日志等操作

Spring MVC 的拦截器和 Filter 过滤器有什么差别?

有以下几点:

  • 功能相同:拦截器和 Filter 都能实现相应的功能,谁也不比谁强
  • 容器不同:拦截器构建在 Spring MVC 体系中;Filter 构建在 Servlet 容器之上
  • 使用便利性不同:拦截器提供了三个方法,分别在不同的时机执行;过滤器仅提供一个方法,当然也能实现拦截器的执行时机的效果,就是麻烦一些

一般拓展性好的框架,都会提供相应的拦截器或过滤器机制,方便的开发人员做一些拓展

REST 面试题

REST 代表着什么?

REST 代表着抽象状态转移,它是根据 HTTP 协议从客户端发送数据到服务端,例如:服务端的一本书可以以 XML 或 JSON 格式传递到客户端

然而,假如你不熟悉REST,我建议你先看看 REST API design and developmentopen in new window 这篇文章来更好的了解它。也可以阅读知乎上的 《怎样用通俗的语言解释 REST,以及 RESTful?》open in new window 讨论

资源是什么?

资源是指数据在 REST 架构中如何显示的。将实体作为资源公开 ,它允许客户端通过 HTTP 方法如:GETopen in new window, POSTopen in new window,PUTopen in new window, DELETE 等读,写,修改和创建资源

什么是安全的 REST 操作?

REST 接口是通过 HTTP 方法完成操作

  • 一些 HTTP 操作是安全的,如 GET 和 HEAD ,它不能在服务端修改资源
  • 换句话说,PUT、POST 和 DELETE 是不安全的,因为他们能修改服务端的资源

所以,是否安全的界限,在于是否修改服务端的资源

什么是幂等操作? 为什么幂等操作如此重要?

有一些HTTP 方法,如:GET,不管你使用多少次它都能产生相同的结果,在没有任何一边影响的情况下,发送多个 GET 请求到相同的URIopen in new window 将会产生相同的响应结果。因此,这就是所谓幂等操作

换句话说,POST方法不是幂等操作open in new window ,因为如果发送多个 POST 请求,它将在服务端创建不同的资源。但是,假如你用 PUT 更新资源,它将是幂等操作。

甚至多个 PUT 请求被用来更新服务端资源,将得到相同的结果

REST 是可扩展的或说是协同的吗?

是的,RESTopen in new window 是可扩展的和可协作的。它既不托管一种特定的技术选择,也不定在客户端或者服务端。你可以用 Javaopen in new window, C++open in new window, Pythonopen in new window, 或 JavaScriptopen in new window 来创建 RESTful Web 服务,也可以在客户端使用它们。

我建议你读一本关于REST接口的书来了解更多,如:RESTful Web Servicesopen in new window

所以这里的“可拓展”、“协同”对应到我们平时常说的,“跨语言”、“语言无关”

REST 用哪种 HTTP 方法呢?

REST 能用任何的 HTTP 方法,但是,最受欢迎的是:

恰好,这四个操作,对上我们日常逻辑的 CRUD 操作

删除的 HTTP 状态返回码是什么 ?

在删除成功之后,您的 REST API 应该返回什么状态代码,并没有严格的规则。它可以返回 200 或 204 没有内容

  • 一般来说,如果删除操作成功,响应主体为空,返回 204open in new window
  • 如果删除请求成功且响应体不是空的,则返回 200

REST API 是无状态的吗?

是的,REST API 应该是无状态的,因为它是基于 HTTP 的,它也是无状态的

REST API 中的请求应该包含处理它所需的所有细节。它不应该依赖于以前或下一个请求或服务器端维护的一些数据,例如会话

REST 规范为使其无状态设置了一个约束,在设计 REST API 时,你应该记住这一点

REST安全吗? 你能做什么来保护它?

安全是一个宽泛的术语。它可能意味着消息的安全性,这是通过认证和授权提供的加密或访问限制提供的

REST 通常不是安全的,需要开发人员自己实现安全机制

参考文章:芋道源码《死磕 Spring MVC 源码分析》open in new window

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址:open in new window