java

位置:IT落伍者 >> java >> 浏览文章

Struts&Spring&Hibernate面试总结


发布日期:2018年03月18日
 
Struts&Spring&Hibernate面试总结

介绍一下Struts的Action类
Struts框架采用ActionServlet和RequestProcessor组件进行集中控制并采用Action组件来处理单项业务ActionServlet把全部提交的请求委托到RequestProcessor对象RequestProcessor使用strutsconfigxml文件检查请求URI找到响应的Action
Action类是用户请求和业务逻辑之间的桥梁每个Action充当客户的一项业务代理这样使得客户请求和Action类之间可以有多个点对点的映射Action类还提供了其它的辅助功能比如:日志(logging)和数据验证(validation)
当控制器收到客户请求的时候在将请求转移到一个Action实例时如果这个实例不存在控制器会首先创建然后会调用这个Action实例的execute()方法在RequestProcessor类预处理请求时在创建了Action的实例后就调用自身的processActionperform()方法该方法再调用Action类的execute()方法 execute()方法再调用模型组件的业务方法完成用户请求的业务逻辑处理然后根据执行结果把请求转发给合适的Web组件Struts Framework为应用系统中的每一个Action类只创建一个实例因为所有的用户都使用这一个实例所以必须确定你的Action 类运行在一个多线程的环境中
ActionForward类
Action类的execute()方法返回一ActionForwad对象ActionForward对象代表了Web资源的逻辑抽象这里的资源可以是JSP页\Java Servlet或Action从execute()方法中返回ActionForward对象有两种方法:
第一:在execute()方法中动态创建一个ActionForward实例
return new ActionForward(&#;Failure&#;&#;/security/errorjsp&#;&#;true&#;);
以上ActionForward构造方法的第一个参数代表ActionForward实例的逻辑名第二个参数指定转发路径第三个参数指定是否进行重定向(true:重定向;false:请求转发)
第二:在Struts配置文件中配置元素
parameter=reqCode
path=/login
scope=request
validate=false
type=comeRedLabeRedCIPframewebLoginAction>
Failure path=/security/errorjsp />

配置了元素后在Struts框架初始化时就会创建存放元素配置信息的ActionForward对象在Action的execute方法中只需调用Actionmapping实例的findForward()方法来获得特定的ActionForward实例:
return mappingfindForward(&#;Failure&#;);
介绍一下Struts的ActionServlet类
ActionServlet继承自javaxservlethttpHttpServlet类其在Struts framework中扮演的角色是中心控制器它提供一个中心位置来处理全部的终端请求按照Servelt的标准所有得Servlet必须在web配置文件(webxml)声明同样ActoinServlet必须在Web Application配置文件(webxml)中描述有关配置信息如下

name>actionname>
class>orgapachestrutsactionActionServletclass>

全部的请求URI以*do的模式存在并映射到这个servlet其配置如下:
mapping>
name>actionname>
*do
mapping>
中心控制器为所有的表示层请求提供了一个集中的访问点当用户向服务器端提交请求的时候实际上信息是首先发送到控制器ActionServlet一旦控制器获得了请求其就会将请求信息传交给一些辅助类(help classes)处理
Struts对MVC的体现
M: 在Struts中模型由JavaBean和EJB组件组成用来实现程序的业务逻辑部分
C: ActionServletRequestProcessor和Struts辅助类来实现控制器ActionServlet是Struts中的核心控制器ActionServlet会根据在Struts配置文件中的配置将控制权转交给相应的Action类Action 类是业务的代理在Action类中可以调用模型组件或者编写其他业务逻辑代码来完成一项具体的业务
V: Struts框架中的视图主要由JSP文件构成在JSP文件中可应用Struts标签和自定义标签来表现模型组件中的数据进行简单的处理ActionForm Bean实际上是一个遵循了特殊约定的JavaBean在Struts中ActionForm Bean可看作为一个中间存储器在视图与控制器之间进行数据传递
Struts框架工作流程
当启动一个采用Struts框架开发的Web应用程序时ActionServlet就会被加载并被初始化然后ActionServlet读取Struts配置文件中的信息并根据文件中的各模块配置来初始化相应的配置对象
当用户的请求属于ActionServlet所处理请求的模式时ActionServlet被调用Struts的处理工作开始:
中央控制器根据用户的请求在Struts配置文件中的元素中查找匹配该请求的子元素如果不存在则返回异常;
在匹配的元素中查找有Scope属性指定的范围中是否存在由name属性指定的ActionForm Bean如果不存在就创建一个新的ActionForm对象然后将用户提交的表单中的数据保存在给ActionFrom对象中并将ActionForm对象放入Scope属性指定的范围内;
如果元素中Validate属性值为true则调用ActionFrom中的Validate()方法进行表单验证;
ActionForm的Validate()方法返回NULL或返回的ActionErrors对象中不包含任何ActionMessage对象则表单验证成功否则表单验证失败ActionServlet将请求转发给Input属性指定的页面;
中央控制器将控制权转交给元素Type属性指定的Action类如果相应的Action类对象不存在则创建该类对象接下来Action类的Execute()方法被调用;
在Action类的Execute()方法中进行业务逻辑处理并返回一个ActionForward对象控制权被交回ActionServletActionServlet将返回的ActionForward对象与元素中的子元素进行匹配并将请求转发给指定的JSP组件;
如果ActionForward对象指定的是另外的Action动作则返回第()步在次执行流程否则生成动态网页返回给用户
Struts中DispatchAction和Action类有什么不同?
DispatchAction是Struts包含的另一个能大量节省开发时间的Action类与其它Action类仅提供单个execute()方法实现单个业务不同DispatchAction允许你在单个Action类中编写多个与业务相关的方法这样可以减少Action类的数量并且把相关的业务方法集合在一起使得维护起来更容易
要使用DispatchAction的功能需要自己创建一个类通过继承抽象的DispatchAction得到例如我们想要提供一个方法来实现对购物车添加商品清单创建了一个类ShoppingCartDispatchAction提供以下的方法:
public ActionForward addItem(ActionMapping mapping ActionForm form HttpServletRequest request HttpServletResponse response){throws Exception;}
那么这个类很可能还需要一个deleteItem()方法从客户的购物车中删除商品清单还有clearCart()方法清除购物车等等这时我们就可以把这些方法集合在单个Action类不用为每个方法都提供一个Action类
在调用ShoppingCartDispatchAction里的某个方法时只需在URL中提供方法名作为参数值就是说调用addItem()方法的 URL看起来可能类似于:http://myhost/storefront/action/cart?method=addItem
其中method参数指定ShoppingCartDispatchAction中要调用的方法参数的名称可以任意配置这里使用的method只是一个例子参数的名称可以在Struts配置文件中自行设定
Struts中最核心的类和包有哪些?
orgapachestrutsaction
控制整个struts framework的运行的核心类组件都在这个包中比如我们上面提到的控制器ActionServlet已经ActionActionFormActionMapping等等struts多了 DynaActionForm 类增加了动态扩展生成FormBean功能
orgapachestrutsactions
这个包是主要作用是提供客户的http请求和业务逻辑处理之间的特定适配器转换功能版本中的部分动态增删FromBean的类也在struts中被Action包的DynaActionForm组件所取代
ornfig
提供对配置文件strutsconfigxml元素的映射这也是sturts中新增的功能
orgapachestrutsutil
Strtuts为了更好支持web application的应用体统了一个些常用服务的支持比如Connection Pool和Message Source
orgapachestrutstaglib
这不是一个包而是是一个客户标签类的集合下面包括Bean TagsHTML TagsLogic TagsNested TagsTemplate Tags这几个用于构建用户界面的标签类
orgapachestrutsvalidator
Struts framework中增加了validator framework用于动态的配置from表单的验证
如何在Web项目中保护JSP源代码不被未经授权的访问和窥视?
把页面文件移到WEBINF 目录下基于Servlet的声明WEBINF不作为Web应用的公共文档树的一部分因此WEBINF 目录下的资源不是为客户直接服务的唯一要注意的是必须把JSP和一个Struts action联系起来
Struts的控制器如何知道什么样的信息转发到什么样的Action类呢?
在struts 中控制器信息转发的配置映射信息是存储在特定的XML文件(比如strutsconfigxml)中的这些配置信息在系统启动的时候被读入内存供struts framework在运行期间使用在内存中每一个元素都与orgapachestrutsactionActionMapping类的一个实例对应
如何用Struts实现国际化?
建立struts的config文件:resources parameter=resourcesapplication/>messageresources标签是指message资源的文件是存放多种语言的提示信息的文件parameter只是文件名没有语言_国家
建立资源文件:默认的资源文件applicationproperties
# &#; international test – 这是注释
testtitle=international application test
testbody=This is a international application test
简体中文的资源文件:application_cnproperties国际化通过unicode码来实现所以要把代码转为unicode码
nativeascii application_cnproperties application_zh_CNproperties
JSP 访问:testtitle/>
Struts Validator验证器
在strutsconfigxml 文件中配置验证器插件

propertyproperty=pathnames value=/WEBINF/validatorrulesxml/WEBINF/validationxml />in>扩展ValidatorForm而不是ActionForm以便它能加载你的Validator资源他根据strutsconfigxml文件中的action的name属性为当前form的调用相应的验证器因此在validatorrulesxml中的form元素的名称属性应该与action的name属性值相匹配使用验证器进行验证的Form不能实现validate()方法
Struts动态Form
动态ActionForm使得用户无须为应用程序的每一个HTML表单创建具体的ActionForm类

bean>在Action中访问动态ActionForm
DynaActionForm dynaForm =(DynaActionForm)form;
String userName = (String)dynaFormget(&#;userName&#;);
String userPwd = (String)dynaFormgetString(&#;userPwd&#;);

Hibernate的执行流程
通过Configuration()configure();读取并解析hibernatecfgxml配置文件
由hibernatecfgxml中的
com/xx/Userhbmxml/>读取解析映射信息
通过configbuildSessionFactory();//得到sessionFactory
sessionFactoryopenSession();//得到session
sessionbeginTransaction();//开启事务
persistent operate;
sessiongetTransaction()commit();//提交事务
关闭session;
关闭sessionFactory;
为什么要用Hibernate
封装了jdbc简化了很多重复性代码
简化了DAO层编码工作使开发更对象化了
移植性好支持各种数据库如果换个数据库只要在配置文件中变换配置就可以了不用改变hibernate代码
支持透明持久化因为hibernate操作的是纯粹的(pojo)java类没有实现任何接口没有侵入性所以说它是一个轻量级框架
Hibernate的延迟加载
get不支持延迟加载load支持延迟加载
hibernate对实体对象和集合实现了延迟加载hibernate对提供了属性的延迟加载功能
hibernate延迟加载就是当使用sessionload(Userclass )或者sessioncreateQuery()查询对象或者属性的时候这个对象或者属性并没有在内存中只有当程序操作数据的时候才会存在内存中这样就实现延迟加载节省了内存的开销从而提高了服务器的性能
Hibernate的缓存机制
一级缓存: session级的缓存也叫事务级的缓存只缓存实体生命周期和session一致不能对其进行管理不用显示的调用二级缓存: sessionFactory缓存也叫进程级的缓存使用第方插件实现的也指缓存实体生命周期和sessionFactory一致可以进行管理
首先配置第放插件我们用的是EHCache在hibernatecfgxml文件中加入

true在映射中也要显示的调用readonly/>
二级缓存之查询缓存: 对普通属性进行缓存如果关联的表发生了修改那么查询缓存的生命周期也结束了
在程序中必须手动启用查询缓存: querysetCacheable(true);
优化Hibernate
使用一对多的双向关联尽量从多的一端维护
如果将t_student(多)表里的classesid字段设置为非空则无法保存不在student这一端维护关系存储student时不会存学生对应的班级在存储班级时需要发出多余的update语句来更新关系
不要使用一对一尽量使用多对一
配置对象缓存不要使用集合缓存
表字段要少表关联不要怕多有二级缓存撑腰
Hibernate对象的三种状态
Persitent状态的对象不能引用Transient对象不然会抛出TransientObjectException异常
Transient(瞬时)状态的特征:
* 在数据库中没有与之匹配的数据
* 没有纳入session的管理
可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联并将数据对应的插入数据库中此时该瞬时对象转变成持久化对象
Persistent(持久)状态的特征:
* persistent状态的对象在数据库中有与之匹配的数据
* 纳入了session的管理
* 在清理缓存(髒数据检查)的时候会和数据库同步
Detached(游离)状态的特征:
* 在数据库中有与之匹配的数据
* 没有纳入session的管理
当与某持久对象关联的session被关闭后该持久对象转变为游离对象当游离对象被重新关联到session上时并再次转变成持久对象游离对象和比瞬时对象相比多了一个数据库记录标识值其它没什么不同
Hibernate的映射方式
一对一: Person和IdCard
添加Person的时候不会出现TransientObjectException异常因为一对一主键关联映射中默认了cascade属性
主键单向: 在Person端
id>
foreign>

idCard

toone name=idCard constrained=true/>
主键双向: 在IdCard端也加入toone name=person/>
外键单向外键双向
一对多:单向双向
单向: 在多的一端加入一个外键指向一的一端它维护的关系是一指向多
tomany>标签的定义示例(在一的一端):
students>
classesid notnull=true/>
tomany class=Student/>

加载时: 加载一的一端时会把多的一端的数据也都加载上(相当于执行两次查找操作)
双向: 在一的一端的集合上使用在对方表中加入一个外键指向一的一端
students inverse=true cascade=all>
classesid/>
tomany class=Student/>

在多一端采用toone>
toone name=classes column=classesid/>
标签指定的外键字段必须和toone>指定的外键字段一致否则引用字段的错误
一对多的关系一般采用双向的在一的一端设置inverse属性把关联关系交给多的一端避免发出多余的update
inverse:主控方外键的关系有谁控制
inverse=false 是主控方外键是由它控制的
inverse=true 是被控方外键与它没关系
要想实现主控方的控制必须将被控方作为主控方的属性
cascade:级联 主表增从表增主表修从表修主表删从表删
多对一:会在多的一端加入一个外键指向一的一端
toone name=group column=groupid/>
多对多:单向双向
hibernate的核心类是什么它们的相互关系是什么?重要的方法是什么?
Configuration 接口:配置Hibernate根据其启动hibernate创建SessionFactory 对象;
SessionFactory 接口:初始化Hibernate充当数据存储源的代理创建session 对象sessionFactory 是线程安全的意味着它的同一个实例可以被应用的多个线程共享是重量级二级缓存;
Session 接口:负责保存更新删除加载和查询对象是线程不安全的避免多个线程共享同一个session是轻量级一级缓存;
Session如下方法: saveloadupdatedelete
Query q=CreateQuery(&#;from Customer where customerName=:customerName&#;)
beginTransaction close transaction commit
Transaction 接口:管理事务;
Query 和Criteria 接口:执行数据库的查询
Hibernate的查询方式 HQL与SQL
执行SQL查询的步骤如下:
()获取Hibernate Session对象;
()编写SQL语句;String sqlString = &#;select {s*} from student s where sname like &#;xxx&#;&#;;
()以SQL语句作为参数调用Session的createSQLQuery方法创建查询对象;
()如果SQL语句包含参数调用Query的setXxx方法为参数赋值;
List l = sessioncreateSQLQuery(sqlString) addEntity(&#;s&#;Studentclass) list();
()调用SQLQuery对象的addEntity或addScalar方法将选出的结果与实体或标量值关联;
()调用Query的list方法返回查询的结果集
Criteriaobject comptosition
Hql: * 属性查询* 参数查询命名参数查询* 关联查询* 分页查询* 统计函数
实体查询例子:
String hql=from User user ;
List list=sessionCreateQuery(hql)list();
HQL面向对象而SQL操纵关系数据库
HQL仅用于查询数据不支持insertupdate和delete语句
Hibernate的主键生成机制
) assigned主键由外部程序负责生成无需Hibernate参与
) increment
主键按数值顺序递增此方式的实现机制为在当前应用实例中维持一个变量以保存着当前的最大值之后每次需要生成主键的时候将此值加作为主键这种方式可能产生的问题是: 如果当前有多个实例访问同一个数据库那么由于各个实例各自维护主键状态不同实例可能生成同样的主键从而造成主键重复异常因此如果同一数据库有多个实例访问此方式必须避免使用
) identity采用数据库提供的主键生成机制如DBSQL ServerMySQL中的主键生成机制
) sequence采用数据库提供的sequence 机制生成主键如Oralce 中的Sequence
) native由Hibernate根据底层数据库自行判断采用identityhilosequence其中一种作为主键生成方式
) uuidhex由Hibernate基位唯一值产生算法生成 进制数值(编码后以长度 的字符串表示)作为主键
) uuidstring uuidhex类似只是生成的主键未进行编码(长度)
) foreign 使用外部表的字段作为主键
在数据库中条件查询速度很慢的时候如何优化?
)建索引)减少表之间的关联
)优化sql尽量让sql很快定位数据不要让sql做全表查询应该走索引把数据量大的表排在前面
)简化查询字段没用的字段不要已经对返回结果的控制尽量返回少量数据
Hibernate 事务处理机制
Hibernate是对JDBC的轻量级对象封装Hibernate本身是不具备Transaction 处理功能的Hibernate的 Transaction实际上是底层的JDBC Transaction的封装或者是JTA Transaction的封装
谈谈SSH整合
Struts(表示层)+Spring(业务层)+Hibernate(持久层)
Struts: Struts是一个表示层框架主要作用是界面展示接收请求分发请求
在MVC框架中Struts属于VC层次负责界面表现负责MVC关系的分发(View: 沿用JSPHTTPFormTagResourse ;Controller: ActionServletstrutsconfigxmlAction)
Hibernate: Hibernate是一个持久层框架它只负责与关系数据库的操作
Spring: Spring是一个业务层框架是一个整合的框架能够很好地黏合表示层与持久层
JDBCHibernate 分页怎样实现?
) Hibernate 的分页:
Query query = sessioncreateQuery(from Student);
querysetFirstResult(firstResult);//设置每页开始的记录号
querysetMaxResults(resultNumber);//设置每页显示的记录数
Collection students = querylist();
) JDBC 的分页:根据不同的数据库采用不同的sql 分页语句
例如: Oracle 中的sql 语句为: SELECT * FROM (SELECT a* rownum r FROM TB_STUDENT) WHERE r between and ″ 查询从记录号 到记录号 之间的所有记录
Servlet都有哪些方法?主要作用是什么?
HttpServlet 类包含 init() destroy() service() 等方法其中 init() 和 destroy() 方法是继承的
() init() 方法
在 Servlet 的生命期中仅执行一次 init() 方法它是在服务器装入 Servlet 时执行的 可以配置服务器以在启动服务器或客户机首次访问 Servlet 时装入 Servlet 无论有多少客户机访问 Servlet 都不会重复执行 init() 例如初始化数据库连接在调用 service() 方法之前应确保已完成了 init() 方法
() service() 方法
service() 方法是 Servlet 的核心每当一个客户请求一个 HttpServlet 对象该对象的 service() 方法就要被调用而且传递给这个方法一个请求(ServletRequest)对象和一个响应(ServletResponse)对象作为参数例如 如果 HTTP 请求方法为 GET 则缺省情况下就调用 doGet() Servlet 应该为 Servlet 支持的 HTTP 方法覆盖 do 功能因为 HttpServletservice() 方法会检查请求方法是否调用了适当的处理方法不必要覆盖 service() 方法只需覆盖相应的 do 方法就可以了
Servlet 的响应可以是下列几种类型:一个输出流浏览器根据它的内容类型(如 text/HTML )进行解释一个 HTTP 错误响应 重定向到另一个 URL servlet JSP
() destroy() 方法
destroy() 方法仅执行一次即在服务器停止且卸装 Servlet 时执行该方法典型的将 Servlet 作为服务器进程的一部分来关闭缺省的 destroy() 方法通常是符合要求的但也可以覆盖它典型的是管理服务器端资源例如如果 Servlet 在运行时会累计统计数据则可以编写一个 destroy() 方法该方法用于在未装入 Servlet 时将统计数字保存在文件中另一个示例是关闭数据库连接
当服务器卸装 Servlet 时将在所有 service() 方法调用完成后或在指定的时间间隔过后调用 destroy() 方法一个 Servlet 在运行 service() 方法时可能会产生其它的线程因此请确认在调用 destroy() 方法时这些线程已终止或完成
() GetServletConfig()方法
GetServletConfig ()方法返回一个 ServletConfig 对象该对象用来返回初始化参数和 ServletContext ServletContext 接口提供有关 servlet 的环境信息

上一篇:面试中常出现的两个Hibernate面试题及解答

下一篇:Servlet 3.0有哪些新的功能和特点?