- SpringMVC是Spring提供的一个用于简化web开发的框架
- MVC框架是表现层框架
3. 开发demo过程
3.1 配置DispatcherServlet
3.2 配置拦截方式
3.3 开发控制层代码(controller 使用相关注解 @Controller @RequestMapping)
3.4 配置springmvc 配置文件
3.4.1 配置扫描controller
3.4.2 配置视图解析器 解析器会将前缀和后缀进行配置 /WEB-INF/jsp/ 与 .jsp
3.4.3 配置自动注册处理器映射器,处理器适配器 只写一个xml标签就可以
3.5 配置DispatcherServlet的contextConfigLocation(本地上下文配置文件: springmvc.xml) 告知DispatcherServlet启动时读取此配置文件
4. springMVC请求处理流程图
4.1 ⽤户发送请求⾄前端控制器DispatcherServlet
4.2 DispatcherServlet收到请求调用HandlerMapping处理器映射器
4.3 处理器映射器根据请求url找到具体的Handler(后端控制器,就是controller),生成处理器对象及处理器拦截器(如果有则生成)一并返回DispatcherServlet
4.4 DispatcherServlet调用HandlerAdapter处理器适配器去调用handler
4.5 处理器适配器执行handler
4.6 Handler执行完成给处理器适配器返回ModelAndView
4.7 处理器适配器向前端控制器返回ModelAndView,ModelAndView是SpringMVC框架的一个底层对象,包括Model和View
4.8 前端控制器请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图
4.9 视图解析器向前端控制器返回View
4.10 前端控制器进行视图渲染,就是将模型数据(在ModelAndView对象中)填充到request域
4.11 前端控制器响应结果
5. springmvc核心三大组件:处理器映射器、处理器适配器、视图解析器
原理剖析
1、springmvc的url-pattern配置及原理剖析
1.1 方式一:配置为带后缀: 比如*.action *.do *.aaa (精确)
1.2 方式二:/ 不会拦截jsp,但是会拦截其他静态资源(比如html,js,css)
1.2.1 为什么会拦截静态资源,因为tomcat中有一个父级web.xml 我们的项目也有一个web.xml,它继承与tomcat的web.xml
1.2.2 父级web.xml中的url-pattern也是/,我们的web.xml也是/,所以我们的web.xml会覆盖掉url-pattern
1.2.3 为什么不拦截.jsp??
1.2.4 因父web.xml中有一个jspServlet,这个Servlet拦截.jsp文件,我们并没有覆写这个配置,所以不拦截jsp,将jsp的处理交给了tomcat
1.2.5 解决/拦截静态资源
1.3 方式三:/* 拦截所有, 包括jsp 拦截到之后会进入handler去寻找对象的handler,实际上拦截jsp并没有用,因为没有jsp路径的handler
2、数据输出机制
2.1 springMVC在handler方法上传入Map,Model和ModelMap参数,并向这些参数中保存数据(放入到请求域),都可以在页面获取到
2.2 他们是什么关系
2.2.1 保存的数据都会放入BindingAwareModelMap,也就是请求域
3、请求参数绑定
3.1 由于请求是使用http超文本传输协议,参数到后台基本都是文本格式(也就是String),所以需要自己转换
3.2 springmvc封装了servlet,所以现在接收参数只要写对应的类型与名字就可以了。因为springmvc会帮我们进行转换的操作,并绑定到handler的形参上
3.3 如果要在springMVC中使用servlet原生对象(HttpServletRequestHttpServletResponseHttpSession),直接在handler方法形参中声明使用即可
3.4 自定义类型转换器,需要实现Converter接口,并在springMVC配置文件中注册,并关联自动注册的处理器映射器
<!-- 自动注册处理器映射器,处理器适配器, 关联自定义转换器 只写这一个标签就可以了-->
<mvc:annotation-driven conversion-service="conversionServiceBean"/>
<!-- 注册自定义类型转换器-->
<bean id="conversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.mango.edu.converter.DateConverter"/>
</set>
</property>
</bean>
3.5 rest请求风格
3.5.1 rest是一个url请求风格(用不用随意)原url: http://localhost:8080/demo/handle04?id=3(先定义资源再定义动作)
3.5.2 rest风格就是 GET POST PUT DELETE代表进行不同的操作(先定义动作再定义字段)
3.6 spring提供的编码过滤器CharacterEncodingFilter filter标签与filter-mapping标签要一起使用 POST请求
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.7 springMVC请求方式过滤器 会检查请求中是否有_Method参数,如果有,就进行请求方式转换
<filter>
<filter-name>httpFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.8 @ResponseBody不再走视图解析器,而是等同于Response响应直接输出数据
Spring MVC 高级技术
1、拦截器(Inteceptor)使用
1.1 监听器、过滤器、拦截器对比
1.1.1 拦截器只会拦截handler(controller),他是springMVC表现层框架自己的,所以需要配置在SpringMVC.xml配置文件中
1.1.1.1 会拦截三次,第一次是执行业务逻辑之前,第二次是执行业务逻辑之后,第三次是执行完业务逻辑跳转页面之后
1.1.2 监听器实现了javax.servlet.ServletContextListener接口的服务器端组件,web应用启动它就会启动,只启动一次,会一直监听,直到web应用销毁
1.1.3 过滤器 对Request请求起到过滤作用,作用在servlet前(请求过来还没有进入servlet)
2、拦截器的执行流程
2.1 拦截器配置
<mvc:interceptors>
<!-- <bean class="com.mango.edu.interceptor.MyInterceptorOne"/>-->
<mvc:interceptor>
<!-- 配置当前拦截器的拦截规则,**代表子目录下的所有url,exclude-mapping代表忽略指定路径的请求(不拦截这些请求)-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/demo/**"/>
<bean class="com.mango.edu.interceptor.MyInterceptorOne"/>
</mvc:interceptor>
</mvc:interceptors>
2.2 执行流程
2.3 多个拦截器执行流程
2.4 多个拦截器执行顺序为springmvc.xml配置文件 配置的顺序执行
3、multipart文件上传
3.1 文件上传解析器配置 springMVC.xml
<!-- 文件上传解析器配置 id名字固定 要不然 spring找不到bean使用不了上传-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置文件上传大小(字节) -1没有限制-->
<property name="maxUploadSize" value="5000000"></property>
</bean>
4、异常处理机制
4.1 HandlerExceptionResolver SpringMVC提供的异常处理器(现在常用的方式是使用注解) @ExceptionHandler 可以写多个捕捉不同的异常
5、SpringMVC重定向是参数传递的问题
5.1 转发和重定向
5.1.1 转发不会丢失参数
5.1.2 重定向会丢失参数 所以需要GET拼接方式接着传递(安全性问题), 或 redirectAttributes.addFlashAttribute("name", name); 将参数放到session中,当跳转成功后,Flash会自动销毁参数
自定义简单MVC框架
1、根据简易流程图手写代码
SpringMVC源码剖析
1、DispatcherServlet继承结构
2、handler方法的执行时机
2.1 doDispatch方法中的1064行代码完成handler方法的调用===>DispatcherServlet.doDispatch(){mv = ha.handle(processedRequest, response, mappedHandler.getHandler());}
3、视图页面渲染时机
3.1 doDispatch方法中的1081行代码完成页面渲染的执行======>DispatcherServlet.doDispatch(){processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}
4、doDispatch核心步骤(大致流程,像拦截器方法,并没有放上)
4.1 调用getHandler(processedRequest);获取到能够处理当前请求的执行链(Handler + 拦截器)
4.2 调用getHandlerAdapter(mappedHandler.getHandler()); 能够执行4.1中的Handler适配器
4.3 调用ha.handle(processedRequest, response, mappedHandler.getHandler()); 适配器执行Handler(总会返回ModelAndView对象)
4.4 调用processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); 完成视图渲染并跳转
5、SpringMVC getHandler细节
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
遍历handlerMappings(一种注解开发,一种早期的配置文件开发)
6、getHandlerAdapter细节
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
遍历handlerAdapters(controller有不同的实现,所以这里也是多个。 根据实现的接口来匹配, 目前是三个 HttpRequestHandler Controller HandlerMethod)
整合SSM
1、Spring + Mybatis + SpringMVC
2、先整合Spring + Mybatis
3、整合目标:
数据库连接池以及事务管理都交给Spring容器来完成
SqlSessionFactory对象应该放到Spring容器中作为单例对象管理
Mapper动态代理对象交给Spring管理,我们从Spring容器中直接获得Mapper的代理对象
4、整合所需jar包
Junit测试jar(4.12版本)
Mybatis的jar(3.4.5)
Spring相关jar(spring-context、spring-test、spring-jdbc、spring-tx、spring-aop、 aspectjweaver)
Mybatis/Spring整合包jar(mybatis-spring-xx.jar)
Mysql数据库驱动jar
Druid数据库连接池的jar
5、整合SpringMVC
web.xml配置springMVC框架启动,启动spring框架(使用监听,配置必要的参数,配置spring的配置文件),spring的配置文件里整合了mybatis与spring的配置,controller必须配置在springMVC配置文件中扫描,不然会出现找不到controller 404
6、错题
mybatis中的ResultMap中的节点都有哪些
SpringData JPA
1、用于dao层的框架,简化数据库开发的,作用于mybatis一样,但是使用方式跟底层是不同的
2、最明显的特点,很多场景,连sql语句都不用写。由Spring提供
3、ORM思想:对象关系映射,通过操作对象来达到操作数据库的目的。例如:xxx.save(user); 向user表中插入了一条数据
SpringDataJpa 源码剖析
1、SpringDataJpa 大部分都当成工具来使用
2、SpringDataJpa 开发dao接口,实现对象是通过动态代理来完成
3、dao层类型是代理对象,代理对象的类型是SimpleJpaRepository
4、想要给对象产生代理对象,是在AbstractApplicationContext.refresh.this.finishBeanFactoryInitialization(beanFactory); 在他生成bean,注入依赖之前拦住他,并寻找想要的源码
5、标签扫描到的接口,在进行BeanDefinition注册的时候,class会被固定的指定为JpaRepositoryFactoryBean
6、JpaRespositoryFactoryBean是一个什么样的类 因为是FactoryBean所以重点关注getObject方法
7、jdk动态代理会生成一个代理对象,类型为SimpleJpaRespositior,该对象的增强逻辑就在JdkDynamicAopProxy类的invoke方法
8、SimpleJpaRepository实现了JpaRepositoryImplementation,JpaRepositoryImplementation继承了JpaRepository与JpaSpecificationExecutor
Spring MVC 组件
1、HandlerMapping(处理器映射器)
1.1 存储了url与handler的映射关系
1.2 标注了@RequestMapping的方法都可以看成是一个Handler
1.3 Handler负责处理请求,HandlerMapping的作用就是找到请求响应的处理器Handler(就是controller)和Interceptor
2、HandlerAdapter(处理器适配器)
2.1 由于handler可以是任意形式的(比如参数的不同), 所以就需要找到对应的handler,HandlerAdapter就是在做这个工作
3、HandlerExceptionResolver
3.1 处理handler产生的异常情况
4、ViewResolver(视图解析器)
4.1 帮我们处理.jsp的页面路径,解耦。 比如将一个jsp文件的前缀路径与后缀路径进行截取,我们在handler只需要书写jsp的名字即可
5、RequestToViewNameTranslator
5.1 获取前端请求的request里面的视图名
6、LocalResolver(国际化)
6.1 每个国家的Local都不相同 比如中国的是zh-CN
7、ThemeResolver(主题处理器,很少使用)
7.1 主题就是你这个系统样式、图片、长什么样之类的
8、MultipartResolver(多元素解析器)
8.1 用来处理上传请求的,文件上传之类
9、FlashMapManager
9.1 用于重定向时的参数传递
10. 这9个组件 全部都在DispatcherServlet.class里面