SpringMVC笔记

(最新更新日期2021-5-4/23时)

ps:文章主要是自学笔记,可能错误颇多,不喜勿喷,欢迎提出宝贵意见

  • ‌注意HandlerExecutionChain对象(其包含了handler和拦截器
  • ‌注意在doDispatcher方法中从viewResolver获得view;和利用该view进行将model放入request,然后再forward,在某一层调用servlet的service方法进入下一个controller。这两个操作是在doDispatcher方法先后调用的两个方法resolveViewName(根据url返回view)和view.render方法.。二者在doDispatcher方法中是同一层面的,有先后关系,没有包裹(父子调用)关系
  • 注意为了更好理解web流程,可以了解Tomcat的基本原理,见简单Tomcat实现

 

  1. controller和原来原始的servlet不太一样,原来所有的请求都会到servlet里的doGet方法里调用业务层(一般叫service层含dao)
  2. 将httpServletRequest req中的数据绑定(填充)到controller中的对应具体方法的参数中去[因为需要知道参数名字[函数参数名没法通过反射获取,只能知道类型,当然类名,类变量名,类方法名可以被获取到;参数名真悲催],最好用注解RequestParam (前面获得了method后,接下来调用method.getAnnotations方法也就得到了参数个数及注解ann,ann.value就获得了参数名,接下来用for循环将req中的与ann.value相同名字的数据按ann在方法中的次序依次放到args[]中),,,之后就调用该controller里的对应该业务方法[实际上是根据前面获得的methodd调用method.invoke (args[])方法,可以看到此时controller里的方法被执行,且参数也传了进去]。详情见SpringMVC中提供两种request参数到方法中参数的绑定方式,中讲解resolveHandlerArguments的部分
  3. 拦截器interceptor以前是在spring-mvc.xml文件中配置的,spring boot没有了该文件了。自定义的拦截器继承HandlerInterceptor(里面有preHandle,postHandle方法)
    由于没有spring-mvc.xml文件了,因而在spring boot像其它配置文件转配置类一样,
    继承WebMvcConfigurerAdapter的自定义MVC配置类(用Configuration注解)中,执行addInterceptor()方法将前面自定义的拦截器对象注册到InterceptorRegisteration中的成员变量HandlerInterceptor中去。
    而InterceptorRegisteration对象是被加入到InterceptorRegistry中的成员变量 registrations(是个List)中去了
    猜测:上面的registrations会根据url在某个方法中传入HandlerMapping的adaptedInterceptors(是个List)中去了(根据url分配到不同handler的handlermapping中)
    实际上是某个handlerMapping的具体实现类
    如RequestMappingHandlerMapping对象在WebMvcConfigurationSupport.java的
    requestMappingHandlerMapping的方法中(其与上面的addInterceptor方法在同一类WebxxxSupport中)
    将上面的registrations放入requestxxxmapper.setInterceptors()中的
    可以看到此时自定义拦截器类已经到了handlermapping实现类中了,之后会放入handlerExecutionChain中
    (注意,上面整个拦截器放入handlermapping的过程应该是在bean初始化的时候进行的,在dispatcher工作之前)

    在doDispacter方法中,在执行handler方法(该handler方法就是对应url的controller的对应方法)前遍历该handler的HandlerExecutionchain里的属于自己的interceptor拦截器方法(依次实现比如session验证,语言检查等环节)
  4. 视图解析器viewResolver作用就是将modelandview中的view根据视图解析xml配置文件(比如前缀Web-INF/test,和后缀.jsp,对之进行拼接,使地址最终变成localhost:8080/Test/web-inf/test/ hello.jsp这样的完整地址)进行视图解析
    下面看doDispatcher方法里会调用processDispatcherResult方法,该方法里调用了初步的render方法,该render方法里主要进行2个操作:
    ‌其一调用resolveViewName根据request里的url解析视图名,返回view对象,在该方法里会出现viewResolver对象进行上面所说的视图解析(拼接地址,新建map)
    ‌其二会调用该view的render方法,该view的某实现类比如下面的InternalResourceView的render方法会调用其renderMergedOutputModel方法,在该方法里的exposeModelAsRequestAttributes()方法中,将model(是map〈key,value〉)传入request的各个同名attribute中,然后按需要forward到对应的jsp页面中(此时该jsp页面可以拿到request中的属性及值,然后jsp页面拿到值后填充或者叫渲染页面成html然后放入response返回给浏览器,可以看到response只有最后一刻及jsp渲染好页面才被放入了最主要的html,其余时间是偶尔放一些东西,而到达jsp页面之前都是基本往request里面获取或放入东西,response基本不参与),,,以前都是在servlet的doGet里对直接对request.setAttribute(key,value)放东西然后经过RequestDispatcher.forward(req,res)到具体的jsp页面,现在springMVC要经过视图解析器viewResolver来往里放东西。如何使用? 
  5. springMVC的三大重点(重点关注DispatcherServlet里doDispatcher方法)
    5.1 建立urlPattern与controller之间的映射map(重点是还要urlPattern与controller里的方法之间的映射,同时需要将controller和其方法上的remapping注解拼接起来重新建立新的map)
    5.2 参数数据绑定和拦截器(上面2,3)
    5.3 视图解析器功能(主要是拼接jsp前缀和后缀,如localhost:8080/WEB-INF/jsps/hello.jsp  +   将model里的数据map放入request的Attributes里,然后forward到已经得到的jsp(见上面3)
    注意不要忘记RequestDispatcher.forward的核心转发作用,其可以转发给其它servlet,jsp,html等资源,而转发到其它servlet其实就相当于又一次要访问新的controller,以后还要经过视图解析,而后两者不必,jsp页面渲染变成的html以及本来是html的放入response返回给浏览器)
    而forward方法最终经过层层调用,在ApplicationFilterChain.java的internalDoFilter方法中调用了servlet.service(request,response)方法,进入了下一个servlet或者说controller的访问

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值