10个知识点让你读懂Spring MVC容器,2024年最新一篇文章教你搞定计算机网络面试

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 拦截器

  • 异常处理

一、Spring MVC的概述

===================

MVC:Model + View + Controller(数据模型 + 视图 + 控制器)

三层架构

========

三层架构:Presentation tier + Application tier + Data tier(展示层 + 应用层 + 数据访问层)

MVC和三层架构的关系

===============

MVC和三层架构的关系, MVC只存在三层架构的展示层。

M实际是数据模型,是包含数据的对象。在Spring MVC里,有一个专门的类叫Model,用来和V之间的数据交互、传值。

V指的是视图界面,包含JSP、freeMarker、Velocity、Thymeleaf、Tile等。

C就是控制器(Spring MVC的注解@Controller的类)。

三层架构是整个应用的的架构,是由Spring框架负责管理的,一般项目结构中都由Service层、Dao层,这两个反馈在应用层和数据访问层。

Spring MVC框架围绕DispatcherServlet这个核心展开,它负责截获请求并将其分派给相应的处理器处理。Spring MVC框架包括注解驱动控制器、请求及响应的信息处理、视图解析、本地化解析、上传文件解析、异常处理以及表单标签绑定等内容。

体系结构

========

Spring MVC是基于Model 2实现的技术框架。Spring MVC通过一个DispatcherServlet接收所有请求,并将具体工作委托给其他组件进行处理。

10个知识点让你读懂Spring MVC容器

Spring MVC体系结构

==================

  1. 客户端发出一个HTTP请求,Web应用服务器接收到这个请求,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),Web容器将该请求转交给DispatcherServlet处理。

  2. DispatcherServlet接收到这个请求后,将根据请求的信息(包括URL、HTTP方法、请求报文头、请求参数、Cookie等)及HandlerMapping的配置找到处理请求的处理器(Handler)。可将HandlerMapping看成路由控制器,将Handler看成目标主机。值得注意的是:Spring MVC中并没有定义一个Handler接口,实际上任何一个Object都可以成为请求处理器。

  3. 当DispatcherServlet根据HandlerMapping得到对应当前请求的Handler后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。 HandlerAdapter是Spring MVC的框架级接口,顾名思义HandlerAdapter是一个适配器,它用统一的接口对各种Handler方法进行调用。

  4. 处理器完成业务逻辑的处理后将运回一个ModelAndView给DispatcherServlet,ModelAndView包含了视图逻辑名和模型数据信息。

  5. ModelAndView中包含的是“逻辑视图名”而非真正的视图对象,DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作。

  6. 当得到真实的视图对象View后,DispatcherServlet就使用这个View对象对ModelAndView中的模型数据进行视图渲染。

  7. 最终客户端得到的响应消息,可能是一个普通的HTML页而,也可能是一个XML或JSON串, 甚至是一张图片或一个PDF文档等不同的媒体形式。

配置DispatcherServlet

=======================

可以在web.xml中配置一个Servlet,并通过指定其处理的URL。

<web-app xmlns=“http://java.sun.com/xml/ns/javaee”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version=“3.0”>

contextConfigLocation

classpath:application-context.xml

org.springframework.web.context.ContextLoaderListener

web

org.springframework.web.servlet.DispatcherServlet

1

web

/

复制代码

  1. 在(1)处,通过contextConfigLocation参数指定业务层Spring容器的配置文件(多个配置文件用 , 分割)。

  2. 在(2)处,ContextLoaderListener是一个ServletLoaderListener,它通过contextConfigLocation指定的Spring配置文件启动业务层的Spring容器。

  3. 在(3)处,配置了名为web的DispatcherServlet,它默认加载/WEB-INF/web-servlet.xml(-servlet.xml)的Spring配置文件,启动Web层的Spring容器。Web层容器将作为业务层容器的子容器,Web层容器可以访问业务层容器的Bean,而业务层容器访问不了Web层容器的Bean。

  4. 在(4)处,通过指定DispatcherServlet处理 /* 全部的HTTP请求。一个web.xml可以配置多个DispatcherServlet,通过其对应的配置,让每个DispatcherServlet处理不同的请求。

DispatcherServlet 的配置参数

===========================

可以通过的属性指定配置参数:

  1. namespace参数:DispatcherServlet对应的命名空间,默认是WEB-INF/-servlet.xml。在显式配置该参数后,新的配置文件对应的路径是WEB-INF/.xml,例如如果将namespace设置为sample,则对应的Spring配置文件为WEB-INFmple.xml。

  2. contextConfigLocation:如果DispatcherServlet上下文对应的Spring配置文件有多个,则可以使用该属性按照Spring资源路径的方式指定,如classpath:sample1.xml,classpath:sample2.xml。

  3. publishContext:默认为true。DispatcherServlet根据该属性决定是否将WebApplicationContext发布到ServletContext的属性列表中,方便调用者可借由ServletContext找到WebApplicationContext实例,对应的属性名为DispatcherServlet#getServletContextAttributeName()的返回值。

  4. publishEvents:默认为true。当DispatcherServlet处理完一个请求后,是否需要向容器发布一个ServletRequestHandleEvent事件。

推荐观看:传送门

=======================================================

Spring容器配置

==============

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xmlns:context=“http://www.springframework.org/schema/context”

xmlns:mvc=“http://www.springframework.org/schema/mvc”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

<context:component-scan base-package=“com.ankeetc.web”/>

<mvc:annotation-driven />

复制代码

基于编程的配置

===========

Spring 4.0已经全面支持Servlet 3.0,可以使用编程的方式配置Servlet容器。在Servlet 3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果发现实现类,就会用它来配置Servlet容器。Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring还提供了一个WebApplicationInitializer基础实现类AbstractAnnotationConfigDispatcherServletInitializer,使得它在注册DispatcherServlet时只需要简单地指定它的Servlet映射即可。

public class WebApplicationInitilalizer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

ServletRegistration.Dynamic registration = servletContext.addServlet(“web”, new DispatcherServlet());

registration.setLoadOnStartup(1);

registration.addMapping(“/”);

}

}

复制代码

DispatcherServlet的内部逻辑

==========================

protected void initStrategies(ApplicationContext context) {

initMultipartResolver(context);

initLocaleResolver(context);

initThemeResolver(context);

initHandlerMappings(context);

initHandlerAdapters(context);

initHandlerExceptionResolvers(context);

initRequestToViewNameTranslator(context);

initViewResolvers(context);

initFlashMapManager(context);

}

复制代码

DispatcherServlet#initStrategies()方法将在WebApplicationContext初始化后执行,此时Spring上下文中的Bean已经初始化完毕,该方法通过反射查找并装配Spring容器中用户自定义的Bean,如果找不到就装配默认的组件实例。

默认组件

========

在DispatcherServlet.properties配置文件里边,指定了DispatcherServlet所使用的默认组件。如果用户希望采用非默认的组件,只需在Spring配置文件中配置自定义的组件Bean即可。

本地化解析器

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

主题解析器

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

处理器解析器

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\

org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

处理器适配器

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\

org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\

org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

异常处理器

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\

org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\

org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

视图名称处理器

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

视图解析器

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

复制代码

10个知识点让你读懂Spring MVC容器

DispatcherServlet装配各型组件的逻辑

==============================

二、注解驱动的控制器

==============

@RequestMapping映射请求

=======================

  1. 在POJO类上标注@Controller,再通过 context:component-scan 扫描到该类,可以是POJO成为一个能处理HTTP请求的控制器。

  2. 在控制器的类定义和方法定义处都可以使用@RequestMapping映射对应的处理方法。

  3. @RequestMapping不但支持标准的URL,还支持Ant风格和{XXX}占位符的URL。

  4. @RequestMapping和value、method、params及headers分别表示请求路径、请求方法、请求参数及报文头的映射条件。

获取请求内容

==========

org.springframework.web.context.request

使用HttpMessageConverter

==========================

HttpMessageConverter接口可以将请求信息转换为一个对象(类型为T),并将对象(类型为T)绑定到请求方法的参数中或输出为响应信息。DispatcherServlet默认已经安装了RequestMethodHandlerAdapter作为HandlerAdapter组件的实现类,HttpMessageConverter即由RequestMethodHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。

HttpMessageConverter的实现类

============================

Spring为HttpMessageConverter提供了众多的实现类:

10个知识点让你读懂Spring MVC容器

实现类

=======

10个知识点让你读懂Spring MVC容器

实现类

=======

10个知识点让你读懂Spring MVC容器

默认的HttpMessageConverter

===========================

RequestMappingHandlerAdapter已经默认装配了以下的HttpMessageConverter:

  • StringHttpMessageConverter

  • ByteArrayHttpMessageConverter

  • SourceHttpMessageConverter

  • AllEncompassingFormHttpMessageConverter

装配其他类型的HttpMessageConverter

===============================

如果需要装配其他类型的HttpMessageConverter,可以在Spring的Web容器上下文中自行定义一个RequestMappingHandlerAdapter,注册若干HttpMessageConverter。如果在Spring web容器中显式定义了一个RequestMappingHandlerAdapter,则Spring MVC将使用它 覆盖 默认的RequestMappingHandlerAdapter。

使用HttpMessageConverter

==========================

  1. 可以使用@RequestBody、@ResponseBody对处理方法进行标注

  2. 可以使用HttpEntity、ResponseEntity作为处理方法的入参或返回值

RestTemplate是Spring的模板类,可以使用该类调用Web服务端的服务,它支持Rest风格的URL。

结论

======

  1. 当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity 时,Spring MVC才会使用注册的HttpMessageConvertor对请求、相应消息进行处理。

  2. 当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity时,Spring 首先根据请求头或响应的Accept属性选择匹配的 HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter,若找不到可用的 HttpMessageConverter 将报错。

  3. @RequestBody、@ResponseBody不需要成对出现。

处理XML和JSON

==============

Spring MVC提供了几个处理XML和JSON格式的请求、响应消息的HttpMessageConverter:

  • MarshallingHttpMessageConverter:处理XML

  • Jaxb2RootElementHttpMessageConverter:处理XML,底层使用JAXB

  • MappingJackson2HttpMessageConverter:处理JSON格式

只要在Spring Web容器中为RequestMappingHandlerAdapter装配好相应的HttpMessageConverter,并在交互中通过请求的Accept指定MIME类型,Spring MVC就可以是服务器端的处理方法和客户端透明的通过XML或JSON格式进行通信。

复制代码

使用@RestController

=====================

@RestController已经标注了@ResponseBody和@Controller,可以直接在控制器上标注该注解,就不用在每个@RequestMapping方法上添加@ResponseBody了。

AsyncRestTemplate

=====================

Spring 4.0提供了AsyncRestTemplate用于以异步无阻塞的方式进行服务访问。

public class WebApplicationInitilalizer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

ServletRegistration.Dynamic registration = servletContext.addServlet(“web”, new DispatcherServlet());

registration.setLoadOnStartup(1);

// 此处要设置为true

registration.setAsyncSupported(true);

registration.addMapping(“/”);

}

}

@RestController

public class AsyncController {

@RequestMapping(value = “/async”, method = RequestMethod.GET)

public Callable async() {

System.out.println(“hello!”);

return new Callable() {

@Override

public String call() throws Exception {

TimeUnit.SECONDS.sleep(5);

return “ASYNC”;

}

};

}

}

public class Main {

public static void main(String[] args) {

AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();

ListenableFuture<ResponseEntity> future = asyncRestTemplate.getForEntity(“http://localhost:8080/async”, String.class);

System.out.println(“return”);

future.addCallback(new ListenableFutureCallback<ResponseEntity>() {

@Override

public void onFailure(Throwable ex) {

System.out.println(“Failure”);

}

最后

image.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

{

AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();

ListenableFuture<ResponseEntity> future = asyncRestTemplate.getForEntity(“http://localhost:8080/async”, String.class);

System.out.println(“return”);

future.addCallback(new ListenableFutureCallback<ResponseEntity>() {

@Override

public void onFailure(Throwable ex) {

System.out.println(“Failure”);

}

最后

[外链图片转存中…(img-HqzTQj2O-1713583267064)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-HgstYbMx-1713583267064)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值