《华为外包java面试题》由会员分享,可在线阅读,更多相关《华为外包java面试题(28页珍藏版)》请在金锄头文库上搜索。
1、SSH 篇(后台)篇(后台)一、一、SSH 概述概述1.1 SSH 的含义的含义当前 J2EE 企业级应用分为三层:表现层-业务层-数据源层,而 SSH 代表了每一层的具体实现,它是三种流行的开源框架的缩写,S-Struts,S-Spring,H-Hibernate。这三者的组合是当前 J2EE 开发的标准模式,也代表了 J2EE 正在朝着简化复杂性,轻量化方向发展,最新 J2EE 6 已证明了这种趋势。1.2 J2EE 开发模式的演变开发模式的演变J2EE 应用一直采用三层加构,即表现层-业务层-数据源层。旧石器时代:J2EE 应用采用表现层-远程 EJB-实体 EJB(或 JDBC) ,这
2、是最为正宗也是最复杂的 J2EE 开发,适用于银行等小部分项目;随后由于微软.NET 的兴起以及其对 J2EE的挑战,正宗的 J2EE 出现了一个变种:表现层-本地 EJB-Ibatis,在这种模型中业务层选择了本地 EJB,同时数据源层也改为 Ibatis,这种模式极大的提高性能,华为大部分项目采用这种构架。在这两种架构中,由于采用了 EJB 组件模型,从而依赖于 EJB 容器,而 EJB 容器以一种全无或全有的方式提供服务,同时业务实现也受制于容器。这种开发模式导致了以下复杂性:依赖于应用服务器,不可移植,开发困难,无法在容器外测试,部署复杂,效率低下。新石器时代:在新石器时代依然采用了三
3、层加构,只是抛弃了 EJB,而采用了 Spring 等轻量级容器,同时持久化由全自动的 Hibernate 承担。在这种架构中,由于放弃了 EJB,放弃了全功能的应用服务器,在节省了软件许可费用的同时也大大提高了软件开发效率。由于web 服务器的可移植也好于应用服务器,从而使得 J2EE 应用可顺利移植。1.3 SSH 与传统开发的比较与传统开发的比较从上面所述可以看出传统 J2EE 开发和 SSH 开发的不同。简言之,传统 J2EE 开发采用 EJB 组件在限制了业务实现的同时也极其复杂,只适用银行等一部分应用;SSH 不强制采用应用服务器,不限制业务实现,透明的持久化从而减化了开发的复杂度
4、,提高了开发效率。二二 、Struts-WEB 层开发的标准层开发的标准2.1 Struts 简介简介Struts 是 Apache 软件基金会的一个开源项目。采用 ServletJSP 技术,实现了基于J2EE Web 应用的 MVC 设计模式的应用框架,是 MVC 经典设计模式中的一个经典产品。使用标准的 JSP 以外,还提供了大量的标签库使用,同时也可以与其他表现层组件技术(产品)进行整合。Struts 出现之前 J2EE Web 层没有统一标准,各个公司都是自有框架,给从业者,企业带来了诸多不便。Struts 采用了经典 MVC 设计,从而事实上成为 WEB 层开发的标准2.2 Str
5、uts 的原理的原理在谈到 Struts 前,简单讲下 MVC 设计模式。MVC 即 Model-View-Controller 的缩写,MVC 减弱了业务逻辑接口和数据接口之间的耦合,同时让视图层更富于变化。MVC 的工作原理,如下图 1 所示:控制器(Controller)-负责转发请求,对请求进行处理。视图(View) - 界面设计人员进行图形界面设计。模型(Model) - 程序员编写程序应有的功能(实现算法等等) 、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。Struts 是 MVC 的一种实现,它将 Servlet 和 JSP 标记用作实现的一部分。Struts 继承
6、了MVC 的各项特性,并根据 J2EE 的特点,做了相应的变化与扩展。Struts 的体系结构与工作原理如下图 2 所示:从图 2 中我们可以知道,Struts 的体系结构包括模型(Model) ,视图(View)和控制器(Controller)三部分。下面让我们从用户发出请示角度来看看 struts 的体系结构(Model 2)与工作原理:(1)首先,用户(通常通过浏览器,如 IE)发出请求,Struts 的控制器(Controller Servlet)得到请求。(2)Struts 控制器通过配置文件得到业务逻辑处理 Action,并调用 Action 的处理用户请求。(3)Action 处
7、理业务业务逻辑(可能查找数据库或调用别的系统) ,处理完成后,填充相关的 Model 对象,并把控制权返回控制器。(4)控制器选择相应的视图(视图从模型里取出数据) ,并返回给用户。2.3 Struts2 简介简介Struts2 提供了对 MVC 的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:拦截器、OGNL 表达式语言、堆栈。下图是 Struts2 的处理流程。一个请求在 Struts2 框架中的处理大概分为以下几个步骤 1 客户端初始化一个指向 Servlet 容器(例如 Tomcat)的请求 2 这个请求经过一系列的过滤器(Filter) (这些过滤器中有一个
8、叫做 ActionContextCleanUp的可选过滤器,这个过滤器对于 Struts2 和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 接着 FilterDispatcher 被调用,FilterDispatcher 询问 ActionMapper 来决定这个请是否需要调用某个 Action 4 如果 ActionMapper 决定需要调用某个 Action,FilterDispatcher 把请求的处理交给ActionProxy 5 ActionProxy 通过 Configuration Manager 询问框架的配置文件,找到需要调用的 Action 类 6 A
9、ctionProxy 创建一个 ActionInvocation 的实例。 7 ActionInvocation 实例使用命名模式来调用,在调用 Action 的过程前后,涉及到相关拦截器(Intercepter)的调用。 8 一旦 Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个 Action 链)一个需要被表示的 JSP或者 FreeMarker 的模版。在表示的过程中可以使用 Struts2 框架中继承的标签。在这个过程中需要涉及到 ActionMapper2.4 Stru
10、ts,Struts2 的比较的比较在在 Action 实现类方面的对比实现类方面的对比:Struts 1 要求 Action 类继承一个抽象基类;Struts 1 的 一个具体问题是使用抽象类编程而不是接口。Struts 2 Action 类可以实现一个 Action 接口,也可以实现其他接口,使可选和定制的服务成为可能。Struts2 提供一 ActionSupport 基类去实现常用的接口。即使 Action 接口不是必须实现的,只有一个包含 execute 方法的POJO 类都可以用作 Struts 2 的 Action 。 线程模式方面的对比线程模式方面的对比:Struts 1 Act
11、ion 是单例模式并且必须是线程安全的,因为仅有 Action 的一个实例来处理所有的请求。单例策略限制了 Struts 1 Action 能做的事,并且要在开发时特别小心。Action 资源必须是线程安全的或同步的;Struts 2 Action 对象为每一个请求产生一个实例,因此没有线程安全问题。 Servlet 依赖方面的对比依赖方面的对比:Struts 1 Action 依赖于 Servlet API,因为 Struts 1 Action 的execute 方法中有 HttpServletRequest 和 HttpServletResponse 方法。Struts 2 Action
12、不再依赖于 Servlet API,从而允许 Action 脱离 Web 容器运行,从而降低了测试 Action 的难度。当然,如果 Action 需要直接访问 HttpServletRequest 和 HttpServletResponse 参数,Struts 2 Action 仍然可以访问它们。但是,大部分时候,Action 都无需直接访问 HttpServetRequest 和 HttpServletResponse,从而给开发者更多灵活的选择。 可测性方面的对比可测性方面的对比:测试 Struts 1 Action 的一个主要问题是 execute 方法依赖于 Servlet API,
13、这使得 Action 的测试要依赖于 Web 容器。为了脱离 Web 容器测试 Struts1 的Action,必须借助于第三方扩展:Struts TestCase,该扩展下包含了系列的 Mock 对象(模拟了 HttpServetRequest 和 HttpServletResponse 对象) ,从而可以脱离 Web 容器测 试 Struts 1 的 Action 类。Struts 2 Action 可以通过初始化、设置属性、调用方法来测试。 封装请求参数的对比封装请求参数的对比:Struts 1 使用 ActionForm 对象封装用户的请求参数,所有的 ActionForm 必须继承一
14、个基类:ActionForm。普通的 JavaBean 不能用作 ActionForm,因此,开发者必须创建大量的 ActionForm 类封装用户请求参数。虽然 Struts 1 提供了动态 ActionForm 来简化 ActionForm 的开发,但依然需要在配置文件中定义ActionForm;Struts2 直接使用 Action 属性来封装用户请求属性,避免了开发者需要大量开发 ActionForm 类的烦琐,实际上,这些属性还可以是包含子属性的 Ric 对象类型。如果开发者依然怀念 Struts 1 ActionForm 的模式,Struts2 提供 ModelDriven 模式,
15、可以让开发者使用单独的 Model 对象来封装用户请求参数,但该 Model 对象无需继承任何 Struts 2 基类,是一个 POJO,从而降低了代码污染。 表达式语言方面的对比表达式语言方面的对比:Struts1 整合了 JSTL,因此可以使用 JSTL 表达式语言。这种表达式语言有基本对象图遍历,但在对集合和索引属性的支持上则功能不强;Struts 2 可以使用 JSTL,但它整合了一种更强大和灵活的表达式语言:OGNL(Object Graph Notation Language) ,因此,Struts 2 下的表达式语言功能更加强大。绑定值到视图的对比:Struts1 使用标准 JS
16、P 机制把对象绑定到视图页面;Struts2 使用“ValueStack ”技术,使标签库能够访问值,而不需要把对象和视图页面绑定在一起。 类型转换的对比类型转换的对比:Struts1 ActionForm 属性通常都是 String 类型。Struts 1 使用commons-Beanutils 进行类型转换,每个类一个转换器,转换器是不可配置的;Struts 2 使用 OGNL 进行类型转换,支持基本数据类型和常用对象之间的转换。 数据校验的对比数据校验的对比:Struts1 支持在 ActionForm 重写 validate 方法中手动校验,或者通过整合 Commons-validator 框架来完成数据校验。Struts 2 支持通过重写 validate 方法进行校验,也支持整合 XWork 校验框架进行校验。 Action 执行控制的对比执行控制的对比:Struts 1 支持每一个模块对应一个请求处理(即生命周期的概念) ,但是模块中的所有 Action 必须共享相同的生命周期。Struts 2 支持通过拦截器堆栈(Interceptor Stac