1 mvc
m model 模型 一般指在应用中的处理业务的javaebean,比如service层 dao层 pojo类等,
通过javabean改变系统的内部状态
v view 视图层 jsp freemaker velocity 流 等
c controller 控制层 负责接收用户请求与转发,模型与视图的之间的桥梁,有核心控制器和业务控制器,
控制器一般不 推荐也不应该写业务代码
2 mvc 流程
向服务器发送请求---核心控制器----------(数据类型转换)(数据封装)(数据校验)-----
业务控制器---调 用modle层处理业务--- 数据绑定 --视图转发---视图(标签与国际化)
考虑 异常处理
3 mvc 优缺点
优点:
1) 分层 易于人员分工。
2)规范 易于维护。
3)松耦合,程序灵活性和扩展性好。
4) 代码重用度更高。
缺点:
1)配置繁琐,代码复杂度增加。
2)代码数量增加。
3)不适合开发小型项目。
4 三大MVC框架(struts1 struts2 springmvc)
1 核心控制器
struts1 ActionServlet 采用Servlet
struts2 FilterDispaatcher StrutsPrepareAndExecuteFilter 采用过滤器
spring mvc DispatchServlet 采用Servlet
2 业务控制器 Action或Conriller
struts1 1 Action 必须继承Action或其子类,业务方法返回ActionForward
2 Action 是单个实例处理每一次请求,在第一次请求的时候创建,以后都用这个实例
注意线程安全问题
struts2 1 只需要一个简单的pojo类
2 可继承ActionSupport(1 实现了Action接口 2 支持action范围,包范围国际化 3 支持校验)
3 方法返回String 或者inputstream (上传下载时)
4 Action 处理每一次请求创建一个新的实例
spring mvc 1 只需要一个简单的pojo类
2 可以继承Controller或其子类
3 方法返回ModelAndView String Map @responsebody等
4 可以使用一个实例处理所有请求,也可以每次请求一个新实例,取决于scope的配置
3 数据封转 这里指的是如何将页面数据封装好传递到业务控制器
struts1 使用ActionForm,ActionForm作为业务类方法的参数,其存放的数据范围有request与
session两种,封转的技术采用apache的BeanUtils填充等方法
struts2 有属性驱动与模型驱动,主要是作为业务类的实例变量,可以说是类级别,因为接收封装
数据的变量为类中的多个方法共享,封装的技术采用ognl.
spring mvc 封装数据的变量作为方法参数,可以说是方法级别的,
封装技术采用beanwapper技术,即bean包装
4 类型转换 在数据封转的过程中,由于页面的数据均是字符串类型,而数据封转bean不一定都匹配,
这就需要类型转换,三大框架都有内置的类型转换器,当内置的类型转换器无法满足需求
时,就需要自定义类型转换器。
struts1 1 实现apache Converter接口,从实现的方法可以看出,这种类型转换器只负责丛页面数据
到业务封转类的转换,反之则没有提供,所以可以说是单向类型转换
2 通过ConvertUtils.register(转换器,转换类型)注册类型转换器,注册要在数据封转之 前
struts2 1 继承StrutsTypeConverter,实则是OGNL的类型转换器,其中有实现的两个方法分别
代表页面---业务类以及业务类---页面,可以说转换是双向的
2 注册类型转换器只需要一个properties文件,从范围来说
1 局部类型转换器 自己action使用
action同目录下建立Action简单类名-conversion.properties
其中内容:action中的bean属性名=包名.转换器类名
2 全局类型转换器 全部action使用 src建立xwork-conversion.properties
其中内容:被转换的类全名=转换器类全名
spring mvc 1 3.0以前 继承 PropertyEditorSupport 实现setAsText方法
在该方法中调用setValue方法 设置返回值,
3.0以后 实现Converter接口 强类型转换 不同数据类型
2 注册类型转换器
1 给控制器或者(注解适配器)注入WebBindingInitializer
2 给 WebBindingInitializer注入类型转换器的登记类
(3.0以前)propertyEditorRegistrars
(3.0) conversionService(FormattingConversionServiceFactoryBean)
对于WebBindingInitializer 可以自己实现通过initBinder方法中的WebDataBinder
注册类型转换器,也可以采用spring的实现类ConfigurableWebBindingInitializer
5 数据校验 在进行数据封转后,在处理业务之前,我们一般要对刚刚封转后的数据进行校验,以便数据
能够符合我们的业务数据规则。
struts1 1 编程式校验 重写form中的validate方法,控制器通过返回的ActionErrors判定校验结果
validate方法会对所有方法进行校验,没有针对具体方法的校验
2 校验框架
1 在struts-config.xml配置验证框架插件启动验证框架
2 要想启用验证框架,我们的form必须继承校验form
3 编写校验规则文件
3 校验没通过返回input所指定的资源
struts2 1 继承ActionSupport 重写validate方法或者编写validatetXxx 方法,
重写vaildate方法会对Action中的所有struts2业务方法进行校验,validatetXxx 方法
是针对具体方法的校验
2 校验框架
在action的同目录下编写Action简单类名-validation.xml文件,该文件中的
验证会对Action中的所有struts2业务方法进行校验,如要校验某个方法,
编写的文件名 是
Action简单类名-action name(struts,xml配置中的name)-validation.xml文件
3 校验没通过返回input所指定的资源
spring mvc 1 使用注解jsr 303 校验
1 需要validation-api-1.0.0.GA 以及选用实现该jsr框架的
具体实现者如hibernate-validator-4.1.0.Final
2 配置<mvc:annotation-driven />的注解支持 会自动注入hibernate校验器
3 方法参数上使用@Valid注解 后面紧跟BindingResult
4 在实体pojo类上使用jsr 303 注解
5 在Controller中之后根据 BindingResult 是否有错误决定跳转的页面
6 国际化
struts1 通过编码把语言环境放进session中,
其中session的名字为org.apache.struts.action.LOCALE,
此后struts1就可以根据这个session值进行选择相对应的语言配置文件进行显示
struts2 1 有action范围,包范围,全局范围的国际化
2 I18N拦截器拦截参数名request_locale的值转换成语言环境放入sesion作用域,
spring mvc 1 LocaleChangeInteceptor拦截器拦截参数名locale
2 配置语言环境 放入session或者cookie中,默认AcceptHeader
7 视图转发
struts1 1 通过ActionForward返回jsp视图
2 通过作用域把值绑定到视图中
struts2 1 视图技术除了jsp之外 还有freemaker velocity 源代码等
2 通过值栈或作用域把值绑定到视图中
spring mvc 1 视图技术除了jsp之外 还有freemaker velocity 等,有多种视图解析器,
默认视图解析器 InternalResourceViewResolver
2 通过 ModelAndView ,map或作用域把值绑定到视图中
8 请求处理流程
struts1 发送请求到达核心控制器Actionservlet,Actionservlet调用一个内部请求处理类
RequestProcessor来处理,根据请求路径得到对应ActionMapping,通过ActionMapping
组件得到业务类Action以及是否绑定ActionForm的信息,如果绑定ActionForm,
则创建或 从作用域取出,并进行ActionForm数据填充,之后进行
ActionForm数据校验,接着创建Action或从Map取出,执行action中的
execute方法返回ActionForward,根据ActionForward组件包含的视图返回响应
struts2 发送请求到达核心控制器过滤器FilterDispatcher或其他,过滤器通过询问ActionMapper
决定是否调用Action,如果调用Action,Struts2将处理交给Action代理,
接着通过配置管理器找到业务类Action,但是Action代理不直接调用Action,而是通过
Action调度器DefaultActionInvocation来调用, ActionInvocation 里有一个迭代器,
里面存放struts2中默认的拦截器 ,调用ActionInvocation中的invoke 时,
会先判断迭代器里是否有拦截器 如果存在拦截器 则执行拦截器的
intercept方法,在intercept方法又执行actionInvocation的invoke方法.
此时又进入了先判断当前的迭代器里是否还有拦截器,如果没有拦截器
则直接执行action类业务方法,从以上调用我们可以看出
struts2是通过一种A类调用B类 B类又调用A类的 非传统递归的方式完成拦截器的调用。
这种调用方式使得拦截器在方法执行前是顺着调用,而方法执行后是倒着调用,struts2
通过拦截器完成了MVC的一些功能,如数据封装 数据校验 国际化 异常等,业务类方法
返回String,根据结果集类型Result-type决定调用那种类进行相应的视图渲染。
struts2通过代理控制目标类Action的访问,加入拦截器的功能,拦截器形成一条链
通过调度器依次调用,使得在目标类被调用前完成所需功能。
spring mvc 发送请求到达核心控制器DispatcherServlet,DispatcherServlet寻找spring容器
中的所有HandlerMapping组件,默认有BeanNameUrlHandlerMapping
与 DefaultAnnotationHandlerMapping,HandlerMapping组件定位业务类Controller,把
该业务类以及相关拦截器放入一个HandlerExecutionChain类中,
由于业务类Controller可以是pojo类或是Controller类型或其他,因此通过适配器
找到对应的Controller业务类类型并执行handle方法,进而执行我们的业务方法,
当然调用业务类方法之前或之后,也涉及到相关拦截器的调用,业务类方法
返回 ModelAndView,通过容器找到配置的视图解析器对视图进行渲染并返回相应,
默认的视图解析器为InternalResourceViewResolver