在早期 Java Web 的开发中,统一把显示层、控制层、显示层的操做所有交给 JSP 或者 Java Bean 来进行处理,存在必定的弊端,例如:JSP 和 Java Bean 之间严重耦合、开发效率低等弊端。javascript
Spring MVC 是 Spring 体系中的一员,提供“模型-视图-控制器”(Model-View-Controller)架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。html
MVC 模式有助于分离应用程序的不一样方面,如输入逻辑,业务逻辑和 UI 逻辑,同时在全部这些元素之间提供松散耦合。java
Spring MVC 也是基于 Servlet 来处理请求的,主要经过 DispatcherServlet 这个 Servlet 来处理请求,处理过程须要经过九大组件来完成,先看到下面这个流程图:python
Spring MVC 处理请求的流程大体如上图所示web
DispatcherServlet
进行处理。DispatcherServlet
将该请求传给了处理器映射组件 HandlerMapping
,并获取到适合该请求的 HandlerExecutionChain 拦截器和处理器对象。DispatcherServlet
还不能直接调用处理器的逻辑,须要进行对处理器进行适配。处理器适配成功后,DispatcherServlet
经过处理器适配器 HandlerAdapter
调用处理器的逻辑,并获取返回值 ModelAndView
对象。DispatcherServlet
须要根据 ModelAndView 解析视图。解析视图的工做由 ViewResolver
完成,若能解析成功,ViewResolver
会返回相应的 View 视图对象。以上就是 Spring MVC 处理请求的全过程,上面的流程进行了必定的简化,主要涉及到最核心的组件,还有许多其余组件没有表现出来,不过这并不影响你们对主过程的理解。面试
总结:客户端发起请求后,最终会交由 DispatcherServlet 来处理,它会经过你的 URI 找到对应的方法,从请求中解析参数,而后经过反射机制调用该方法,将方法的执行结果设置到响应中,若是存在对应的 View 对象,则进行页面渲染,实际上就是将请求转发到指定的 URLspring
那么接下来就简单介绍一下 DispatcherServlet
和九大组件(按使用顺序排序的):json
组件 | 说明 |
---|---|
DispatcherServlet | Spring 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 对象 |
FlashMapManager | FlashMap 管理器,负责重定向时,保存参数至临时存储(默认 Session) |
Spring MVC 对各个组件的职责划分的比较清晰。DispatcherServlet
负责协调,其余组件则各自作份内之事,互不干扰。后端
@Controller
注解标记一个类为 Spring Web MVC 控制器 Controller。Spring MVC 会将扫描到该注解的类,而后扫描这个类下面带有 @RequestMapping
注解的方法,根据注解信息,为这个方法生成一个对应的处理器对象,在上面的 HandlerMapping 和 HandlerAdapter组件中讲到过。api
固然,除了添加 @Controller
注解这种方式之外,你还能够实现 Spring MVC 提供的 Controller
或者 HttpRequestHandler
接口,对应的实现类也会被做为一个处理器对象
@RequestMapping
注解,在上面已经讲过了,配置处理器的 HTTP 请求方法,URI等信息,这样才能将请求和方法进行映射。这个注解能够做用于类上面,也能够做用于方法上面,在类上面通常是配置这个控制器的 URI 前缀
@RestController
注解,在 @Controller
基础上,增长了 @ResponseBody
注解,更加适合目前先后端分离的架构下,提供 Restful API ,返回例如 JSON 数据格式。固然,返回什么样的数据格式,根据客户端的 ACCEPT
请求头来决定。
@RequestMapping
:可注解在类和方法上;@GetMapping
仅可注册在方法上
@RequestMapping
:可进行 GET、POST、PUT、DELETE 等请求方法;@GetMapping
是 @RequestMapping
的 GET 请求方法的特例,目的是为了提升清晰度。
两个注解都用于方法参数,获取参数值的方式不一样,@RequestParam
注解的参数从请求携带的参数中获取,而 @PathVariable
注解从请求的 URI 中获取
可使用 @ResponseBody
注解,或者使用包含 @ResponseBody
注解的 @RestController
注解。
固然,仍是须要配合相应的支持 JSON 格式化的 HttpMessageConverter 实现类。例如,Spring MVC 默认使用 MappingJackson2HttpMessageConverter
WebApplicationContext 是实现 ApplicationContext 接口的子类,专门为 WEB 应用准备的
入口不一样
配置映射不一样,
视图不一样
Spring MVC 拦截器有三个加强处理的地方:
能够经过拦截器进行权限检验,参数校验,记录日志等操做
有如下几点:
通常拓展性好的框架,都会提供相应的拦截器或过滤器机制,方便的开发人员作一些拓展
REST 表明着抽象状态转移,它是根据 HTTP 协议从客户端发送数据到服务端,例如:服务端的一本书能够以 XML 或 JSON 格式传递到客户端
然而,假如你不熟悉REST,我建议你先看看 REST API design and development 这篇文章来更好的了解它。也能够阅读知乎上的 《怎样用通俗的语言解释 REST,以及 RESTful?》 讨论
资源是指数据在 REST 架构中如何显示的。将实体做为资源公开 ,它容许客户端经过 HTTP 方法如:GET, POST,PUT, DELETE 等读,写,修改和建立资源
REST 接口是经过 HTTP 方法完成操做
因此,是否安全的界限,在于是否修改服务端的资源
有一些 HTTP 方法,如:GET,无论你使用多少次它都能产生相同的结果,在没有任何一边影响的状况下,发送多个 GET 请求到相同的URI 将会产生相同的响应结果。所以,这就是所谓幂等操做
换句话说,POST方法不是幂等操做 ,由于若是发送多个 POST 请求,它将在服务端建立不一样的资源。可是,假如你用 PUT 更新资源,它将是幂等操做。
甚至多个 PUT 请求被用来更新服务端资源,将获得相同的结果
是的,REST 是可扩展的和可协做的。它既不托管一种特定的技术选择,也不定在客户端或者服务端。你能够用 Java, C++, Python, 或 JavaScript 来建立 RESTful Web 服务,也能够在客户端使用它们。
我建议你读一本关于REST接口的书来了解更多,如:RESTful Web Services 。
因此这里的“可拓展”、“协同”对应到咱们平时常说的,“跨语言”、“语言无关”
REST 能用任何的 HTTP 方法,可是,最受欢迎的是:
刚好,这四个操做,对上咱们平常逻辑的 CRUD 操做
在删除成功以后,您的 REST API 应该返回什么状态代码,并无严格的规则。它能够返回 200 或 204 没有内容
是的,REST API 应该是无状态的,由于它是基于 HTTP 的,它也是无状态的
REST API 中的请求应该包含处理它所需的全部细节。它不该该依赖于之前或下一个请求或服务器端维护的一些数据,例如会话
REST 规范为使其无状态设置了一个约束,在设计 REST API 时,你应该记住这一点
安全是一个宽泛的术语。它可能意味着消息的安全性,这是经过认证和受权提供的加密或访问限制提供的
REST 一般不是安全的,须要开发人员本身实现安全机制