




免费预览已结束,剩余90页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MVC主要任务:封装请求参数到JavaBean数据类型转换和验证调用业务代码返回数据数据转向某个页面展示结果MVC的理解?MVC是模型(model)视图(view)控制器(controller)的缩写,一种软件设计思想, 强制性的把应用程序的输入、处理和输出分开。解耦和,任何的重定向都能解耦和MVC中的模型、视图、控制器它们分别担负着不同的任务。1 视图:视图是用户看到并与之交互的界面。视图向用户显示相关的数据,并接受用户的输入。视图不进行任何业务逻辑处理。-获取数据/显示数据2 模型:模型表示业务数据和业务处理。相当于JavaBean。一个模型能为多个视图提供数据。这提高了应用程序的重用性-处理数据(model层对容器的依赖性越少越好,model层是多实例还是单例)3 控制器:当用户单击Web页面中的提交按钮时,控制器接受请求并调用相应的模型去处理请求。然后根据处理的结果调用相应的视图来显示处理的结果。-控制流程MVC的处理过程:首先控制器接受用户的请求,调用(委托)相应的模型来进行业务处理,并返回数据给控制器。控制器调用相应的视图来显示处理的结果。并通过视图呈现给用户。MVC 优点:(DRY/SRP(单一职责原则)/松耦合/可重用/可维护/便于开发)1 分层有助于管理复杂的应用程序,可以在一个时间内专门关注一个方面。例如,可以在不依赖业务逻辑的情况下专注于视图设计。2 让应用程序的测试更加容易。3 也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。最典型的MVC就是JSP + servlet + javabean的模式三层架构的理解srtuts2struts2的理解Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开大致流程:(1) 客户端(Client)向Action发用一个请求(Request)(2) Container通过web.xml映射请求,并获得控制器(Controller)的名字(3) 容器(Container)调用控制器(StrutsPrepareAndExecuteFilter)。在Struts2.1以前调用FilterDispatcher,Struts2.1以后调用StrutsPrepareAndExecuteFilter(4) 控制器(Controller)通过ActionMapper获得Action的信息(5) 控制器(Controller)调用ActionProxy(6) ActionProxy读取struts.xml文件获取action和interceptor stack的信息。(7) ActionProxy把request请求传递给ActionInvocation(8) ActionInvocation根据配置文件加载相关的所有Interceptor拦截器,通过代理模式调用Action和interceptor(9) 根据action的配置信息,产生result(10)Result信息返回给ActionInvocation根据struts.xml中配置的result,决定进行下一步输出(11)产生一个HttpServletResponse响应(12)产生的响应行为发送给客服端。详细流程:1.启动服务器(tomcat),StrutsPrepareAndExecuteFilter的init方法执行将会自动加载配置文件perties在struts2-core-2.3.7.jar中org.apache.struts2包里面(常量的默认值)struts-default.xml在struts2-core-2.3.7.jar(Bean、313/273行18个默认拦截器、结果类型)struts-plugin.xml在struts-Xxx-2.3.7.jar(在插件包中存在,配置插件信息)struts-config-browser-plugin-2.3.7.jar里面有struts.xml该文件是web应用默认的struts配置文件(实际开发中,通常写struts.xml)perties该文件是Struts的默认配置文件 (配置常量)web.xml该文件是Web应用的配置文件(配置常量)2.请求经过一系列的过滤器(Filter),StrutsPrepareAndExecuteFilter被调用doFilter方法被执行 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; prepare.setEncodingAndLocale(request, response);/设置编码格式:utf-8,根据perties prepare.createActionContext(request, response);/创建actionContext prepare.assignDispatcherToThread();/整个的过程都在当前线程中执行request = prepare.wrapRequest(request);/对request进行了包装ActionMapping mapping = prepare.findActionMappin(request, response, true);/询问ActionMapper来决定这个请求是否需要调用某个Action。如果是.action: dispatcher.serviceAction()3.createAcitonContext() /利用容器创建值栈 ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack(); /构建值栈的结构,把request,session,application等封装成一些map,再把这些map放入到大map中 stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext); /把大map的引用指向了ActionContext中的Map context; ctx = new ActionContext(stack.getContext(); /把整个actionContext放入到了当前线程中,因为actionContext中有valueStack,所以valueStack也在当前线程中, /这样就保证了数据的安全性并且在一个线程范围内可以共享数据 ActionContext.setContext(ctx);说明:1、创建actionContext对象2、创建ValueStack(实现类OnglValueStack)3、把整个的actionContext放入到了ThreadLocal中4.serviceAction() ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); /* * 因为在struts2容器中有太多的参数request,response,valueStack,session,application,paramters 所以struts2容器对当前的请求中用到所有的数据封装在了ActionContext中的map中 */ extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack); String namespace = mapping.getNamespace(); String name = mapping.getName(); String method = mapping.getMethod(); /创建actionProxy ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false); proxy.execute()方法 prepare.cleanupRequest(request);/把struts2过程中的数据全部清空了5.在createActionProxy中执行了如下的内容: 重点: 执行了DefaultActionInvocation中的init方法 createAction(contextMap)调用ObjectFactory中buildAction 创建了action stack.push(action); 把action放入到了对象的栈顶 contextMap.put(action, action);把action放入到map中 List interceptorList = new ArrayList(proxy.getConfig().getInterceptors(); interceptors = interceptorList.iterator(); 获取所有的拦截器,并且返回了迭代器的形式6.DefaultActionInvocation中的invoke方法 1、按照顺序的方式执行所有的拦截器 2、执行action中的方法 3、执行结果集 4、按照倒序的方式执行拦截器 invoke() /调用了拦截器 if (interceptors.hasNext() final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); String interceptorMsg = interceptor: + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); finally UtilTimerStack.pop(interceptorMsg); resultCode = invokeActionOnly();/执行action /在执行结果集之前执行PreResultListener if (preResultListeners != null) for (Object preResultListener : preResultListeners) PreResultListener listener = (PreResultListener) preResultListener; String _profileKey = preResultListener: ; try UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); finally UtilTimerStack.pop(_profileKey); executeResult();/执行结果集 总结:在执行过滤器filter的过程中 1、创建ActionContext 1、创建actionContext 2、创建值栈 3、把actionContext加入到当前线程中 2、创建actionProxy 执行DefaultActionInvocation的init方法 1、创建action 2、把action放入到栈顶 3、创建所有的拦截器,并且产生拦截器的迭代器 3、执行Proxy的execute方法 proxy.execute()-invocaction.invoke方法 1、执行所有的拦截器 2、执行当前请求的action 3、执行RreResultListener 4、执行结果集 4、清除数据 在finally中,这样即便出错,也能清除struts2的缺点: 1、整个的核心流程写死了,想动态的添加内容那是不可能的 2、struts2的错误处理 action-throws-defaultActionInvocation.invoke-throws- StrutsActionProxy.execute-throws-Dispatcher.serviceAction try catch(ConfigurationException e) sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e); catch (Exception e) sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); 这样的错误处理意味着:在action中的每一个方法中都得try catch,在架构中不是一个聪明的做法 3、ajax与struts2整合的时候,在ajax的请求过程中,如果后台是servlet,如果后台报错,servlet内部会设置状态码, 这个时候,会触发ajax的onreadystatechange函数,js的客户端就会得到该值知道:后台出错了 但是struts2框架是会跳转到错误模板页面,对于状态码并没有进行设置 所以在ajax与struts2结合的过程中,因为struts2内部没有设置错误处理的状态码, 如果想要在客户端的error方法中输出内容,必须在action中通过手动设置拦截器 ExceptionMappingInterceptor在这个拦截器中可以处理,也可以不处理 List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); 如果没有右边的配置,list将为null,如果为null,继续抛 如果不为null,则处理。 Servlet的优点1、 是mvc的基础,其他的框架比如struts1,struts2,webwork都是从servlet基础上发展过来的。所以掌握servlet是掌握mvc的关键。2、 Servlet把最底层的api暴漏给程序员,使程序员更能清楚的了解mvc的各个特点。3、 程序员可以对servlet进行封装。Struts2就是从servlet中封装以后得到的结果。4、 市场上任何一个mvc的框架都是servlet发展过来的,所以要想学好struts2这个框架,了解servlet的运行机制很关键。Servlet的缺点1、 每写一个servlet在web.xml中都要做相应的配置。如果有多很servlet,会导致web.xml内容过于繁多。2、 这样的结构不利于分组开发。3、 在servlet中,doGet方法和doPost方法有HttpServletRequest和HttpServletResponse参数。这两个参数与容器相关,如果想在servlet中作单元测试,则必须初始化这两个参数。4、 如果一个servlet中有很多个方法,则必须采用传递参数的形式,分解到每一个方法中。获取值栈的路径说明:1、 值是一样的,说明只有一个对象2、 因为有一种是从request域中获取的,所以是一次请求值栈的内存总图说明: 从上图中可以看出valueStack总共分为两个部分: 对象栈:root Map栈:_values值栈放值取值ActionContext.getContext().getValueStack().push(Object) ,将对象注入到栈顶对象栈 JSP页面通过 javabean 属性名 获取ActionContext.getContext().getValueStack().set(k ,v ) ,把一个对象变成map存入到对象栈中 JSP页面 “key” 获得ActionContext.getContext().put(k ,v ) 把一个数据直接放入到map栈中 , JSP页面“#key” 获取 #相当于ActionContext.getContext()结果集在struts-default.xml文件中,如下面所示: 说明:从上述可以看出总共10种类型默认类型为ServletDispatcherResult即转发。结果类型可以是这10种结果类型的任意一种。 Struts1-PK-Struts2Action 类: Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。线程模式: Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。 Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)Servlet 依赖: Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。 Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。可测性: 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展Struts TestCase提供了一套Struts1的模拟对象(来进行测试)。 Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。捕获输入: Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。 Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。表达式语言: Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。 Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言Object Graph Notation Language (OGNL).绑定值到页面(view): Struts 1使用标准JSP机制把对象绑定到页面中来访问。 Struts 2 使用 ValueStack技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。类型转换: Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。 Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。校验: Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。 Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性Action执行的控制: Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。 Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。拦截器在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截器是AOP的一种实现策略。1、struts2在web.xml配置的Filter叫什么?org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter负责初始化整个Struts框架并且处理所有的请求Struts2.1以前调用FilterDispatcher2、struts2的Action有几种编写方式?第一种 创建类,这个类不继承任何类,不实现任何的接口第二种 创建类,实现接口 Action接口第三种 创建类,继承类 ActionSupport类,ActionSupport类是Action接口的实现类3、能否在struts2的Action定义多个业务方法?如何做到不同的请求访问Action的不同方法?1method=.2使用通配符方式进行操作 ,使用符号 * 星号代表任意内容3访问Action中指定方法,不进行配置 1) 在工程中使用 动态方法调用 ,必须保证 struts.enable.DynamicMethodInvocation = true 常量值 为true 2) 在action的访问路径 中 使用 !方法名 4、xml进行struts2请求参数校验时,指定方法的校验和所有方法校验文件命名规则是什么?对指定的方法校验1针对动作类中的指定方法进行校验,使用SkipValidation注解2格式 Action类名-ActionName(元素name属性)-validation.xml 例如 : 校验AddCustomerAction中execute方法 配置 校验文件名字:AddCusotmerAction-addcustomer-validation.xml所有方法校验在Action所在包 编写 Action类名-validation.xml 对Action所有业务方法进行校验5、struts2的Action中如何使用ServletAPI?1、 在Action 中解耦合方式 间接访问 Servlet API - 使用 ActionContext 对象actionContext = ActionContext.getContext();1) actionContext.getParameters(); 获得所有请求参数Map集合 2) actionContext.put(company, 传智播客); / actionContext.get(company) 对request范围存取数据 3) actionContext.getSession(); 获得session数据Map,对Session范围存取数据4) actionContext.getApplication(); 获得ServletContext数据Map,对应用访问存取数据 2、 使用接口注入的方式,操作Servlet API (耦合)ServletContextAware : 注入ServletContext对象ServletRequestAware :注入 request对象ServletResponseAware : 注入response对象3、 在Action中直接通过 ServletActionContext 获得Servlet APIServletActionContext.getRequest() : 获得request对象 (session)ServletActionContext.getResponse() : 获得response 对象ServletActionContext.getServletContext() : 获得ServletContext对象6、struts2中有哪些常用结果类型?1) dispatcher :Action 转发给 JSP2) chain :Action转发到另一个Action (同一次请求)3) redirect : Action重定向到 JSP4) redirectAction :Action重定向到另一个Action stream:下载用的(文件上传和下载时再议)plainText:以纯文本的形式展现内容7、struts2中修改常量的方式?1) struts2 默认常量 在 perties 中配置 2) 开发者自定义常量 struts.xml (要求)格式 : perties (要求)格式 : struts.devMode = trueweb.xml 格式 : struts2org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterstruts.devModetrue1、struts2中全局国际化的配置方式?创建一系列的资源文件 ,命名规范 :基本名称_小写语言_大写的国家.propertiesmessages_zh_CN.properties messages_en_US.properties 配置全局国际化使用struts.xml里面常量进行配置常量名称:struts.custom.i18n.resources常量的值:资源文件的基本名称如果资源文件在src下面,直接写基本名称如果资源文件在包下面,添加包路径 比如 cn/itcast/messages2、addFieldError、addActionError 有何区别?都是com.opensymphony.xwork2.ActionSupport类下的方法.addActionError (String anErrorMessage)添加一个Action级别的错误消息到ActionanErrorMessage: 错误消息,被存放在List列表中显示消息的标签是(如放在jsp页面中): 显示全部的 Action级别的错误消息,可以加CSS代码addFieldError (String fieldName, String errorMessage)给一个字段(属性) 添加错误消息fieldName: 字段(属性)名errorMessage: 错误消息,被存放在一个Map中(其中key存放的是fieldName,value存放的是errorMessage)。 显示消息的标签是(如放在jsp页面中): 显示全部的错误消息(用addFieldError方法添加的 )ActionSupport类还有一个 public boolean hasErrors () 方法, 其实他内部实现是这样的:(hasActionErrors() | hasFieldErrors() , 分别检查有无Action级别的错误信息, 有无Fidld级别的错误的信息.只要一个为真, 就跳回input 实图, 并显示错误信息(如果你写了相应的标签)3、简述struts2中自定义拦截器实现步骤?第一步 创建类 ,继承AbstractInterceptor类或继承MethodFilterInteceptor类第二步 重写AbstractInterceptor类里面 intercept方法,在这个方法中写逻辑最后执行下一个操作return invocation.invoke();第三步 注册拦截器在要拦截的action所在的package里面声明拦截器在要拦截的action里面使用拦截器如果使用自定义的拦截器,默认的拦截器不会执行的,手动使用默认的拦截器/index.jsp/demo100.jsp4、简述struts2 的拦截器执行原理?1.struts2中的拦截器的实现原理是AOP思想.2.struts2中的拦截器采用的是责任链模式当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute()或指定的方法前,在struts.xml中查找与该Action对应的拦截器。如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。一个有序链表,通过递归调用,变成了一个堆栈执行过程,将一段有序执行的代码变成了2段执行顺序完全相反的代码过程,从而巧妙地实现了AOP。这也就成为了Struts2的Action层的AOP基础2个非常重要的推论:1. 如果在拦截器中,我们不使用invocation.invoke()来完成堆栈中下一个元素的调用,而是直接返回一个字符串作为执行结果,那么整个执行将被中止。2. 我们可以以invocation.invoke()为界,将拦截器中的代码分成2个部分,在invocation.invoke()之前的代码,将会在Action之前被依次执行,而在invocation.invoke()之后的代码,将会在Action之后被逆序执行。由此,我们就可以通过invocation.invoke()作为Action代码真正的拦截点,从而实现AOP5、使用struts2如何实现多文件上传?1第一步 上传表单页面,满足三个要求,提交到action里面,要求:多个文件上传项name属性值必须要一样2创建action,在action实现多文件的上传,在action中使用数组形式得到多个文件的信息private File uploadImages;/得到上传的文件private String uploadImagesContentType;/得到文件的类型private String uploadImagesFileName;/得到文件的名称3遍历数组,得到每一个文件的信息,一个一个上传到服务器中if(uploadImages!=null&uploadImages.length0) for(int i=0;iuploadImages.length;i+) File destFile = new File(realpath,uploadImageFileNamesi); FileUtils.copyFile(uploadImagesi, destFile); 1、什么是值栈?贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个ValueStack 对象).相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象ValueStack 是 struts2 提供一个接口,实现类 OgnlValueStack - 值栈对象 (OGNL是从值栈中获取数据的 )每个Action实例都有一个ValueStack对象 (一个请求 对应 一个ValueStack对象 )在其中保存当前Action 对象和其他相关对象 (值栈中 是有Action 引用的 )Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中,request中 (值栈对象 是 reque
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 圣诞活动策划方案美术教案
- 滨州安全培训题库课件
- 山东公司品牌策划活动方案
- 建筑方案设计学什么内容
- 道路亮化照明施工方案
- 滨州住建安全培训平台课件
- 新都建筑维修方案设计招标
- 陕西老房屋拆迁施工方案
- 厦门立体植物墙施工方案
- 揭阳下沉式庭院施工方案
- 2025年银行内部审计部门财务审计员竞聘考试指南
- 流水别墅案例分析
- 录入与排版教学计划
- 2023免拆底模钢筋桁架楼承板图集
- 云计算技术基础应用教程(HCIA-Cloud)PPT完整全套教学课件
- 呼吸衰竭小讲课课件
- 成人学士学位英语1000个高频必考词汇汇总
- GB/T 5271.29-2006信息技术词汇第29部分:人工智能语音识别与合成
- 全屋定制家居橱柜衣柜整装安装服务规范
- 沥青及沥青混合料试验作业指导书
- 义务教育阶段学生艺术素质测评指标体系小学音乐
评论
0/150
提交评论