【Spring】30、Spring,SpringMVC用法汇总
SpringMVC的工作原理图:
springMVC中的几个组件:
前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU。
处理器映射器(HandlerMapping):根据URL去查找处理器
处理器(Handler):(需要程序员去写代码处理逻辑的)
处理器适配器(HandlerAdapter):会把处理器包装成适配器,这样就可以支持多种类型的处理器,类比笔记本的适配器(适配器模式的应用)
视图解析器(ViewResovler):进行视图解析,多返回的字符串,进行处理,可以解析成对应的页面
1、前端控制器DispatcherServlet(不需要工程师开发),由框架提供
作用:接收请求,响应结果,相当于转发器,中央处理器。有了dispatcherServlet减少了其它组件之间的耦合度。
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
2、处理器映射器HandlerMapping(不需要工程师开发),由框架提供
作用:根据请求的url查找Handler
HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
4、处理器Handler(需要工程师开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。
5、视图解析器View resolver(不需要工程师开发),由框架提供
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。
一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面。
6、视图View(需要工程师开发jsp...)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)
核心架构的具体流程步骤如下:
第一步:用户发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找
第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)
第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)
第五步:处理器适配器去执行Handler
第六步:Handler执行完给处理器适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView
第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析
第九步:视图解析器像前端控制器返回View
第十步:前端控制器对视图进行渲染
第十一步:前端控制器向用户响应结果
filter过滤器
过滤器放在web资源之前,可以在请求抵达它所应用的web资源(可以是一个Servlet、一个Jsp页面,甚至是一个HTML页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。Filter:用来拦截请求,处于客户端与被请求资源之间,目的是重用代码。Filter链,在web.xml中哪个先配置,哪个就先调用。在filter中也可以配置一些初始化参数。
Filter 有如下几个用处:
- 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。
- 根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。
- 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。
- 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
自定义数据绑定---HandlerMethodArgumentResolver:
自定义一个CurrentUserHandlerMethodArgumentResolver实现HandlerMethodArgumentResolver
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor;
Object arg = null;
String[] paramValues = webRequest.getParameterValues(parameter.getParameterName());
if (paramValues != null) {
arg = paramValues.length >= 1 ? paramValues[0] : null;
} ParamCheck paramCheck = parameter.getParameterAnnotation(ParamCheck.class);
if(null != paramCheck){
try {
this.doCheck(arg, paramCheck, parameter.getParameterName(),parameter.getParameterType().getSimpleName());
} catch (RuntimeException e) {
LOGGER.error(e);
}
return arg;
} EntityCheck entityCheck = parameter.getParameterAnnotation(EntityCheck.class);
if(null != entityCheck){
arg = this.buildEntityFromParam(parameter, webRequest);
try {
this.doCheck(arg, entityCheck, parameter,webRequest);
} catch (RuntimeException e) {
LOGGER.error(e);
}
return arg;
}
return arg;
}
controller中接收参数,加上自定义注解 @EntityCheck
@RequestMapping(value = "/test")
@ResponseBody
public ModelMap test(@EntityCheck String str) {
ModelMap mm = new ModelMap();
try {
mm.addAttribute("message", "success");
mm.addAttribute("status", "0");
} catch (Exception e) {
e.printStackTrace();
mm.addAttribute("message", "failure");
mm.addAttribute("status", "1");
}
return mm;
}
springMVC对异常处理的支持
处理优先级,当发生异常的时候,SpringMVC会如下处理:
(1)SpringMVC会先从配置文件找异常解析器HandlerExceptionResolver
(2)如果找到了异常异常解析器,那么接下来就会判断该异常解析器能否处理当前发生的异常
(3)如果可以处理的话,那么就进行处理,然后给前台返回对应的异常视图
(4)如果没有找到对应的异常解析器或者是找到的异常解析器不能处理当前的异常的时候,就看当前的Controller中有没有提供对应的异常处理器,如果提供了就由Controller自己进行处理并返回对应的视图
(5)如果配置文件里面没有定义对应的异常解析器,而当前Controller中也没有定义的话,那么该异常就会被抛出来。
<!--错误处理器-->
<bean id="exceptionHandler" class="wangzhongqiu.spring.springmvc.resolver.MobileExceptionHandler"/>
public class MobileExceptionHandler implements HandlerExceptionResolver { private static Log logger = LogFactory.getLog(MobileExceptionHandler.class); private static final Log LOGGER = LogFactory.getLog(MobileExceptionHandler.class);
private static final int DEFAULT_STATUS_CODE = 1000;
private static final int UPLOAD_SIZE_EXCEEDED = 300601;
private static final String SPLIT = ""; @Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ex.printStackTrace();
ModelAndView mav = new ModelAndView();
Map<String, Object> model = new HashMap();
// 默认异常信息 “请求失败,请稍后再试”
int status = DEFAULT_STATUS_CODE;
MappingJackson2JsonView view = new MappingJackson2JsonView();
try {
// 必选参数丢失
if (ex instanceof MissingServletRequestParameterException
|| ex instanceof HttpRequestMethodNotSupportedException || ex instanceof TypeMismatchException) {
status = 1001;
} else if (ex instanceof MaxUploadSizeExceededException) {
LOGGER.error("上传头像图片大小超过系统限制", ex);
status = UPLOAD_SIZE_EXCEEDED;
}
model.put("message", "错误");
model.put("status", status);
view.setAttributesMap(model);
mav.setView(view);
} catch (Exception e) {
LOGGER.error(e);
}
return mav;
}
}
使用BeanNameAutoProxyCreator创建代理
BeanNameAutoProxyCreator是自动代理创建器的三种(BeanNameAutoProxyCreator,DefaultAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator)之一.
它是根据拦截器和设置的Bean的名称表达式做匹配来创建代理.
<bean id="exposerProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>databaseInterceptor</value>
<value>suspendAutoRepayInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>*Controller</value>
</list>
</property>
<property name="proxyTargetClass" value="true"/>
</bean>
<bean id="databaseInterceptor" class="wangzhongqiu.spring.springmvc.interceptor.DatabaseInterceptor"/>
<bean id="suspendAutoRepayInterceptor" class="wangzhongqiu.spring.springmvc.interceptor.SuspendAutoRepayInterceptor"/>
public class DatabaseInterceptor implements MethodInterceptor {
private static final Logger DB_INC_LOG = LoggerFactory.getLogger(DatabaseInterceptor.class); @Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
try {
Method method = methodInvocation.getMethod();
if (method != null && method.getAnnotation(ReadOnlyDataSource.class) != null) {
DataSourceProvider.setDataSource(AvailableDataSources.READ);
DB_INC_LOG.info("The method 【" + method.getName() + "】 will use read-only datasource.");
}
return methodInvocation.proceed();
} finally {
DataSourceProvider.clearDataSource();
}
}
}
BeanNameAutoProxyCreator是一个BeanPostProcessor.它在Bean实例化随后,调用回调org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization进行后期处理来完成代理的创建.
BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。
BeanFactory是个 Factory ,实际上是实例化,配置和管理众多bean的容器, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。
如果一个类实现了FactoryBean接口,那么getBean得到的不是他本身了,而是它所产生的对象,如果我们希望得到它本身,只需要加上&符号即可。
public class PersonFactoryBean implements FactoryBean<Person>{ private String personInfo; public Person getObject() throws Exception {
Person person = new Person () ;
String [] infos = personInfo.split ( "," ) ;
person.setName(infos[0]);
person.setAddress(infos[1]);
person.setAge(Integer.parseInt(infos[2]));
return person;
} public Class<Person> getObjectType() {
return Person.class;
} public boolean isSingleton() {
return true;
}
}
<bean id="personFactory" class="com.hik.MavenTest.PersonFactory">
<property name="personInfo" value="gh2,address2,22"></property>
</bean>
context包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory的功能。多数用户可以以一种完全的声明式方式来使用ApplicationContext,甚至不用去手工创建它
Context包的基础是位于org.springframework.context包中的ApplicationContext接口。它是由BeanFactory接口集成而来,提供BeanFactory所有的功能。
====================相关文章=============================
Spring ContextLoaderListener与DispatcherServlet所加载的applicationContext的区别
ApplicationContext ,ApplicationContextAware,Listener,Event 的关系解读
<load-on-startup>0</load-on-startup>配置
========================================================
spring MVC 拦截器和<mvc:annotation-driven />的详解
Spring MVC handlerMapping和handlerAdapter
Spring MVC HandlerInterceptorAdapter的使用
Spring MVC 自定义数据绑定---HandlerMethodArgumentResolver
========================================================
spring aop 使用BeanNameAutoProxyCreator创建代理
Spring的BeanFactoryPostProcessor和BeanPostProcessor
Spring代理。BeanNameAutoProxyCreator 与 ProxyFactoryBean
========================================================
BeanFactory 和 ApplicationContext的区别
========================================================
Java的位运算符详解实例——与(&)、非(~)、或(|)、异或...
===================未完成================================
ProxyFactoryBean
ServletContextAware
【Spring】30、Spring,SpringMVC用法汇总的更多相关文章
- Spring 定时器Quartz的用法
Spring定时器Quartz的用法也很简单,需要引入quartz-all-1.5.2.jar java代码如下: package com.coalmine.desktop; import java. ...
- Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页
本博客介绍基于Spring Data这款orm框架加上Jquery.pagination插件实现的分页功能. 介绍一下Spring Data框架 spring Data : Spring 的一个子项目 ...
- 【Spring学习】SpringMVC demo搭建
前言:今天会通过IDEA建立一个SpringMVC的demo项目,在其中会涉及到一些基础模块和相关知识,然后结合这个具体的知识点,理解清楚SpringMVC的框架原理(以图的形式展示),顺藤摸瓜分析源 ...
- Spring MVC的WebMvcConfigurerAdapter用法收集(零配置,无XML配置)
原理先不了解,只记录常用方法 用法: @EnableWebMvc 开启MVC配置,相当于 <?xml version="1.0" encoding="UTF-8&q ...
- 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码
前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...
- Spring MVC RedirectAttributes的用法解决办法
Spring MVC RedirectAttributes的用法很久没发过技术贴了,今天对于一个问题纠结了2小时,遂放弃研究用另一种方法解决,奈何心中一直存在纠结,发帖求解 我先解释下什么是Redir ...
- spring整合mybatis,springMVC的0配置文件方式
0配置文件的形式主要是采用spring3.0提供的@configuration注解和spring容器在启动的时候会加载实现了WebApplicationInitializer的类,并调用其onStar ...
- spring容器和springmvc容器,以及web容器的关系
说到spring和springmvc,其实有很多人分不清他们有什么区别,认为它俩是一样的,如果你问他项目里用的什么MVC技术,他会说我们用的spring和mybatis,或者spring和hibern ...
- spring(一)--spring/springmvc/spring+hibernate(mybatis)配置文件
这篇文章用来总结一下spring,springmvc,spring+mybatis,spring+hibernate的配置文件 1.web.xml 要使用spring,必须在web.xml中定义分发器 ...
随机推荐
- Html5与Css3知识点拾遗(八)
css5新增的元素与属性 表单内元素的属性 1. form属性 之前必须书写在表单内部.而在Html5中,可以放在任何位置,为元素指定一个form属性,属性值为该表单的id,就可以声明该元素属于指定表 ...
- Coding能力提升小技巧
一.使用变量的一般原则 1.变量初始化原则: 通常在变量声明时初始化; 在靠近变量第一次使用的位置初始化; 在类的构造函数里初始化变量. 2.作用域: 使变量引用局部化,即把引用到变量的地方尽可能集中 ...
- hadoop2.4.0伪分布式搭建以及分布式关机重启后datanode没起来的解决办法
1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...
- WeexSDK之注册Components
先来看一下注册Components的源码: + (void)_registerDefaultComponents { [self registerComponent:@"container& ...
- Java学习笔记30(集合框架四:List接口)
List接口继承自Collection接口 具有重要的三大特点: 1.有序集合:存入和取出的顺序一致 2.此接口的用户可以对列表中每个元素插入位置精确的控制:可以通过索引操作 3.可以存储重复元素 L ...
- MySQL程序端启动密码错误解决方法
MySQL程序端启动密码错误解决方法 一般启动MySQL程序端,都是用mysql -uroot -p命令,当然前提是你的环境变量已经配好了. 为了连接服务器,当调用mysql时,通常需要提供一个MyS ...
- Testing - 软件测试知识梳理 - 相关词汇
测试策略 描述测试工程的总体方法和目标:根据测试需求,描述在什么测试阶,依据什么测试要素和目标,进行什么种类的测试,使用什么样的测试方法和工具. 测试策略的制定主要包含如下内容: 确定测试过程要使用的 ...
- [EXP]K8 DotNetNuke DNNspot Store <=3.0 GetShell exploit
# Exploit Title: DotNetNuke DNNspot Store <=3.0 GetShell exploit# Date: 31/03/2015# Author: K8拉登哥 ...
- 金三银四季来了!Java 面试题大放送,能答对70%就去BATJTMD试试~
摘要: 2019,相对往年我们会发现今年猎头电话少了,大部分企业年终奖缩水,加薪幅度也不如往年,选择好offer就要趁早,现在开始准备吧,刷一波Java面试题,能回答70%就去BATJTMD大胆试试~ ...
- 安装apache 后,找不到服务,解决办法
在命令行进入安装apache的bin目录下,在输入命令:httpd.exe -k install -n Apache版本号 回车即可注意:要在管理员的身份下进入cmd (C:\Windows\SysW ...