Struts&Spring&Hibernate面试总结
2023-07-06
1、 介绍一下Struts的Action类
Struts框架采用ActionServlet和RequestProcessor组件进行集中控制,并采用Action组件来处理单项业务。ActionServlet把全部提交的请求委托到RequestProcessor对象,RequestProcessor使用struts-config.xml文件检查请求URI找到响应的Action。
Action类是用户请求和业务逻辑之间的桥梁,每个Action充当客户的一项业务代理,这样使得客户请求和Action类之间可以有多个点对点的映射。Action类还提供了其它的辅助功能,比如:日志(logging)和数据验证(validation)。
当控制器收到客户请求的时候,在将请求转移到一个Action实例时,如果这个实例不存在,控制器会首先创建,然后会调用这个Action实例的execute()方法。在RequestProcessor类预处理请求时,在创建了Action的实例后,就调用自身的processActionperform()方法,该方法再调用Action类的execute()方法, execute()方法再调用模型组件的业务方法,完成用户请求的业务逻辑处理,然后根据执行结果把请求转发给合适的Web组件。Struts Framework为应用系统中的每一个Action类只创建一个实例。因为所有的用户都使用这一个实例,所以必须确定你的Action 类运行在一个多线程的环境中。
2、 ActionForward类
Action类的execute()方法返回一ActionForwad对象.ActionForward对象代表了Web资源的逻辑抽象。这里的资源可以是JSP页Java Servlet或Action.从execute()方法中返回ActionForward对象有两种方法:
第一:在execute()方法中,动态创建一个ActionForward实例,
return new ActionForward(“Failure”,”/security/error.jsp”,”true”);
以上ActionForward构造方法的第一个参数代表ActionForward实例的逻辑名,第二个参数指定转发路径,第三个参数指定是否进行重定向.(true:重定向;false:请求转发)
第二:在Struts配置文件中配置元素.
parameter="reqCode"
path="/login"
scope="request"
validate="false"
type="com.eRedLab.eRedCIP.frame.web.LoginAction">
配置了元素后,在Struts框架初始化时就会创建存放元素配置信息的ActionForward对象。在Action的execute方法中只需调用Actionmapping实例的findForward()方法,来获得特定的ActionForward实例:
return mapping.findForward(“Failure”);
3、 介绍一下Struts的ActionServlet类
ActionServlet继承自javax.servlet.http.HttpServlet类,其在Struts framework中扮演的角色是中心控制器。它提供一个中心位置来处理全部的终端请求。按照Servelt的标准,所有得Servlet必须在web配置文件(web.xml)声明。同样,ActoinServlet必须在Web Application配置文件(web.xml)中描述,有关配置信息如下。
action
org.apache.struts.action.ActionServlet
全部的请求URI以*.do的模式存在并映射到这个servlet,其配置如下:
action
*.do
中心控制器为所有的表示层请求提供了一个集中的访问点。当用户向服务器端提交请求的时候,实际上信息是首先发送到控制器ActionServlet,一旦控制器获得了请求,其就会将请求信息传交给一些辅助类(help classes)处理。
4、 Struts对MVC的体现
M: 在Struts中,模型由JavaBean和EJB组件组成,用来实现程序的业务逻辑部分.
C: ActionServlet,RequestProcessor和Struts辅助类来实现控制器。ActionServlet是Struts中的核心控制器ActionServlet会根据在Struts配置文件中的配置将控制权转交给相应的Action类。Action 类是业务的代理,在Action类中可以调用模型组件或者编写其他业务逻辑代码来完成一项具体的业务。
V: Struts框架中的视图主要由JSP文件构成,在JSP文件中可应用Struts标签和自定义标签来表现模型组件中的数据进行简单的处理。ActionForm Bean实际上是一个遵循了特殊约定的JavaBean,在Struts中ActionForm Bean可看作为一个中间存储器在视图与控制器之间进行数据传递。
5、 Struts框架工作流程
当启动一个采用Struts框架开发的Web应用程序时,ActionServlet就会被加载并被初始化。然后ActionServlet读取Struts配置文件中的信息,并根据文件中的各模块配置来初始化相应的配置对象。
当用户的请求属于ActionServlet所处理请求的模式时,ActionServlet被调用,Struts的处理工作开始:
1.中央控制器根据用户的请求,在Struts配置文件中的元素中查找匹配该请求的子元素,如果不存在,则返回异常;
2.在匹配的元素中查找有Scope属性指定的范围中是否存在由name属性指定的ActionForm Bean.如果不存在,就创建一个新的ActionForm对象,然后将用户提交的表单中的数据保存在给ActionFrom对象中,并将ActionForm对象放入Scope属性指定的范围内;
3.如果元素中Validate属性值为true,则调用ActionFrom中的Validate()方法进行表单验证;
4.ActionForm的Validate()方法返回NULL或返回的ActionErrors对象中不包含任何ActionMessage对象,则表单验证成功。否则表单验证失败,ActionServlet将请求转发给Input属性指定的页面;
5.中央控制器将控制权转交给元素Type属性指定的Action类,如果相应的Action类对象不存在,则创建该类对象。接下来Action类的Execute()方法被调用;
6.在Action类的Execute()方法中进行业务逻辑处理,并返回一个ActionForward对象。控制权被交回ActionServlet,ActionServlet将返回的ActionForward对象与元素中的子元素进行匹配,并将请求转发给指定的JSP组件;
7.如果ActionForward对象指定的是另外的Action动作,则返回第(1)步在次执行流程,否则生成动态网页返回给用户。
6、 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配置文件中自行设定。
7、 Struts中最核心的类和包有哪些?
1. org.apache.struts.action
控制整个struts framework的运行的核心类、组件都在这个包中,比如我们上面提到的控制器ActionServlet。已经Action,ActionForm,ActionMapping等等。struts1.1比1.0多了 DynaActionForm 类。增加了动态扩展生成FormBean功能
2. org.apache.struts.actions
这个包是主要作用是提供客户的http请求和业务逻辑处理之间的特定适配器转换功能,而1.0版本中的部分动态增删FromBean的类,也在struts1.1中被Action包的DynaActionForm组件所取代
3. org.apache.struts.config
提供对配置文件struts-config.xml元素的映射。这也是sturts1.1中新增的功能
4. org.apache.struts.util
Strtuts为了更好支持web application的应用,体统了一个些常用服务的支持,比如Connection Pool和Message Source。
5. org.apache.struts.taglib
这不是一个包,而是是一个客户标签类的集合。下面包括Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags这几个用于构建用户界面的标签类。
6 . org.apache.struts.validator
Struts1.1 framework中增加了validator framework,用于动态的配置from表单的验证。
8、 如何在Web项目中保护JSP源代码不被未经授权的访问和窥视?
把页面文件移到WEB-INF 目录下。基于Servlet的声明,WEB-INF不作为Web应用的公共文档树的一部分。因此,WEB-INF 目录下的资源不是为客户直接服务的。唯一要注意的是必须把JSP和一个Struts action联系起来。
9、 Struts的控制器如何知道什么样的信息转发到什么样的Action类呢?
在struts 中,控制器信息转发的配置映射信息是存储在特定的XML文件(比如struts-config.xml)中的。这些配置信息在系统启动的时候被读入内存,供struts framework在运行期间使用。在内存中,每一个元素都与org.apache.struts.action.ActionMapping类的一个实例对应。
10、 如何用Struts实现国际化?
建立struts的config文件:,message-resources标签是指message资源的文件,是存放多种语言的提示信息的文件。parameter只是文件名,没有语言_国家
建立资源文件:默认的资源文件application.properties
# — international test – 这是注释
test.title=international application test
test.body=This is a international application test
简体中文的资源文件:application_cn.properties,国际化通过unicode码来实现,所以要把代码转为unicode码
native2ascii application_cn.properties application_zh_CN.properties
JSP 访问:
11、 Struts Validator验证器
在struts-config.xml 文件中配置验证器插件
扩展ValidatorForm而不是ActionForm,以便它能加载你的Validator资源。他根据struts-config.xml文件中的action的name属性为当前form的调用相应的验证器,因此在validator-rules.xml中的form元素的名称属性应该与action的name属性值相匹配。使用验证器进行验证的Form不能实现validate()方法。
12、 Struts动态Form
动态ActionForm使得用户无须为应用程序的每一个HTML表单创建具体的ActionForm类。
在Action中访问动态ActionForm
DynaActionForm dynaForm =(DynaActionForm)form;
String userName = (String)dynaForm.get(“userName”);
String userPwd = (String)dynaForm.getString(“userPwd”);
1、 Hibernate的执行流程
1. 通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件。
2. 由hibernate.cfg.xml中的
读取解析映射信息。
3. 通过config.buildSessionFactory();//得到sessionFactory。
4. sessionFactory.openSession();//得到session。
5. session.beginTransaction();//开启事务。
6. persistent operate;
7. session.getTransaction().commit();//提交事务
8. 关闭session;
9. 关闭sessionFactory;
2、 为什么要用Hibernate
1. 封装了jdbc,简化了很多重复性代码。
2. 简化了DAO层编码工作,使开发更对象化了。
3. 移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate代码。
4. 支持透明持久化,因为hibernate操作的是纯粹的(pojo)java类,没有实现任何接口,没有侵入性。所以说它是一个轻量级框架。
3、 Hibernate的延迟加载
get不支持延迟加载,load支持延迟加载。
hibernate2对实体对象和集合实现了延迟加载,hibernate3对提供了属性的延迟加载功能
hibernate延迟加载就是当使用session.load(User.class, 1)或者session.createQuery()查询对象或者属性的时候,这个对象或者属性并没有在内存中,只有当程序操作数据的时候,才会存在内存中,这样就实现延迟加载,节省了内存的开销,从而提高了服务器的性能。
4、 Hibernate的缓存机制
一级缓存: session级的缓存也叫事务级的缓存,只缓存实体,生命周期和session一致。不能对其进行管理。不用显示的调用。二级缓存: sessionFactory缓存,也叫进程级的缓存,使用第3方插件实现的,也指缓存实体,生命周期和sessionFactory一致,可以进行管理。
首先配置第3放插件,我们用的是EHCache,在hibernate.cfg.xml文件中加入
true 在映射中也要显示的调用,
二级缓存之查询缓存: 对普通属性进行缓存。如果关联的表发生了修改,那么查询缓存的生命周期也结束了。
在程序中必须手动启用查询缓存: query.setCacheable(true);
5、 优化Hibernate
1. 使用一对多的双向关联,尽量从多的一端维护。
如果将t_student(多)表里的classesid字段设置为非空,则无法保存。不在student这一端维护关系,存储student时不会存学生对应的班级,在存储班级时需要发出多余的update语句来更新关系
2. 不要使用一对一,尽量使用多对一。
3. 配置对象缓存,不要使用集合缓存。
4. 表字段要少,表关联不要怕多,有二级缓存撑腰。
6、 Hibernate对象的三种状态
Persitent状态的对象不能引用Transient对象,不然会抛出TransientObjectException异常
Transient(瞬时)状态的特征:
* 在数据库中没有与之匹配的数据
* 没有纳入session的管理
可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
Persistent(持久)状态的特征:
* persistent状态的对象在数据库中有与之匹配的数据
* 纳入了session的管理
* 在清理缓存(脏数据检查)的时候,会和数据库同步
Detached(游离)状态的特征:
* 在数据库中有与之匹配的数据
* 没有纳入session的管理
当与某持久对象关联的session被关闭后,该持久对象转变为游离对象。当游离对象被重新关联到session上时,并再次转变成持久对象。游离对象和比瞬时对象相比,多了一个数据库记录标识值,其它没什么不同。
7、 Hibernate的映射方式
一对一: Person和IdCard
添加Person的时候,不会出现TransientObjectException异常,因为一对一主键关联映射中,默认了cascade属性。
主键单向: 在Person端
idCard
主键双向: 在IdCard端也加入
外键单向,外键双向
一对多: 单向,双向
单向: 在多的一端加入一个外键指向一的一端,它维护的关系是一指向多
标签的定义示例(在一的一端):
加载时: 加载一的一端时,会把多的一端的数据也都加载上(相当于执行两次查找操作)
双向: 在一的一端的集合上使用,在对方表中加入一个外键指向一的一端
在多一端采用
标签指定的外键字段必须和指定的外键字段一致,否则引用字段的错误。
一对多的关系一般采用双向的,在一的一端设置inverse属性,把关联关系交给多的一端,避免发出多余的update。
inverse:主控方,外键的关系有谁控制
inverse=false 是主控方,外键是由它控制的
inverse=true 是被控方,外键与它没关系
要想实现主控方的控制必须将被控方作为主控方的属性
cascade:级联, 主表增从表增,主表修从表修,主表删从表删
多对一: 会在多的一端加入一个外键,指向一的一端
多对多: 单向,双向
8、 hibernate的核心类是什么,它们的相互关系是什么?重要的方法是什么?
Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象;
SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建session 对象,sessionFactory 是线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级、二级缓存;
Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session,是轻量级、一级缓存;
Session如下方法: save,load,update,delete,
Query q=CreateQuery(“from Customer where customerName=:customerName”)
beginTransaction, close, transaction, commit
Transaction 接口:管理事务;
Query 和Criteria 接口:执行数据库的查询。
9、 Hibernate的查询方式, HQL与SQL
执行SQL查询的步骤如下:
(1)获取Hibernate Session对象;
(2)编写SQL语句;String sqlString = “select s.* from student s where s.name like ‘xxx’”;
(3)以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象;
(4)如果SQL语句包含参数,调用Query的setXxx方法为参数赋值;
List l = session.createSQLQuery(sqlString) .addEntity(“s”,Student.class) .list();
(5)调用SQLQuery对象的addEntity或addScalar方法将选出的结果与实体或标量值关联;
(6)调用Query的list方法返回查询的结果集。
Criteria,object comptosition
Hql: * 属性查询 * 参数查询、命名参数查询 * 关联查询 * 分页查询 * 统计函数
实体查询例子:
String hql=”from User user ”;
List list=session.CreateQuery(hql).list();
HQL面向对象,而SQL操纵关系数据库
HQL仅用于查询数据,不支持insert,update和delete语句
10、 Hibernate的主键生成机制
1) assigned 主键由外部程序负责生成,无需Hibernate参与。
2) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是: 如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
3) identity 采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
4) sequence 采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
5) native 由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
6) uuid.hex 由Hibernate基128位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
7) uuid.string uuid.hex类似,只是生成的主键未进行编码(长度16)。
8) foreign 使用外部表的字段作为主键。
11、 在数据库中条件查询速度很慢的时候,如何优化?
1)建索引 2)减少表之间的关联
3)优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面
4)简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
12、 Hibernate 事务处理机制
Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction 处理功能的,Hibernate的 Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装
13、 谈谈SSH整合
Struts(表示层)+Spring(业务层)+Hibernate(持久层)
Struts: Struts是一个表示层框架,主要作用是界面展示,接收请求,分发请求。
在MVC框架中,Struts属于VC层次,负责界面表现,负责MVC关系的分发。(View: 沿用JSP,HTTP,Form,Tag,Resourse ;Controller: ActionServlet,struts-config.xml,Action)
Hibernate: Hibernate是一个持久层框架,它只负责与关系数据库的操作。
Spring: Spring是一个业务层框架,是一个整合的框架,能够很好地黏合表示层与持久层。
14、 JDBC,Hibernate 分页怎样实现?
1) Hibernate 的分页:
Query query = session.createQuery(”from Student”);
query.setFirstResult(firstResult);//设置每页开始的记录号
query.setMaxResults(resultNumber);//设置每页显示的记录数
Collection students = query.list();
2) JDBC 的分页:根据不同的数据库采用不同的sql 分页语句
例如: Oracle 中的sql 语句为: “SELECT * FROM (SELECT a.*, rownum r FROM TB_STUDENT) WHERE r between 2 and 10″ 查询从记录号2 到记录号10 之间的所有记录。
15、 Servlet都有哪些方法?主要作用是什么?
HttpServlet 类包含 init() 、 destroy() 、 service() 等方法。其中 init() 和 destroy() 方法是继承的。
(1) init() 方法
在 Servlet 的生命期中,仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。 可以配置服务器,以在启动服务器或客户机首次访问 Servlet 时装入 Servlet 。 无论有多少客户机访问 Servlet ,都不会重复执行 init() 。例如,初始化数据库连接。在调用 service() 方法之前,应确保已完成了 init() 方法。
(2) service() 方法
service() 方法是 Servlet 的核心。每当一个客户请求一个 HttpServlet 对象,该对象的 service() 方法就要被调用,而且传递给这个方法一个”请求”(ServletRequest)对象和一个”响应”(ServletResponse)对象作为参数。例如, 如果 HTTP 请求方法为 GET ,则缺省情况下就调用 doGet() 。 Servlet 应该为 Servlet 支持的 HTTP 方法覆盖 do 功能。因为 HttpServlet.service() 方法会检查请求方法是否调用了适当的处理方法,不必要覆盖 service() 方法。只需覆盖相应的 do 方法就可以了。
Servlet 的响应可以是下列几种类型:一个输出流,浏览器根据它的内容类型(如 text/HTML )进行解释。一个 HTTP 错误响应 , 重定向到另一个 URL 、 servlet 、 JSP 。
(3) destroy() 方法
destroy() 方法仅执行一次,即在服务器停止且卸装 Servlet 时执行该方法。典型的,将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的,但也可以覆盖它,典型的是管理服务器端资源。例如,如果 Servlet 在运行时会累计统计数据,则可以编写一个 destroy() 方法,该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。
当服务器卸装 Servlet 时,将在所有 service() 方法调用完成后,或在指定的时间间隔过后调用 destroy() 方法。一个 Servlet 在运行 service() 方法时可能会产生其它的线程,因此请确认在调用 destroy() 方法时,这些线程已终止或完成。
(4) GetServletConfig()方法
GetServletConfig ()方法返回一个 ServletConfig 对象,该对象用来返回初始化参数和 ServletContext 。 ServletContext 接口提供有关 servlet 的环境信息。