Struts,Hibernate和spring整合
现在我们使用spring来进行注入,从而将它们整合到一起,图形如下:
下面给出代码,UserDaoImpl类的代码如下:
@Component("userDao")
public class UserDaoImpl implements UserDao{
private SessionFactory sessionFactory;
public void save(User u) {
sessionFactory.openSession().save(u);
}
//@Transactional(propagation=Propagation.REQUIRED)
public boolean checkUserExistsWithName(String username) {
List<User> users = (List<User>)sessionFactory.openSession().createQuery("from User u where u.username=:username").setString("username", username).list();
if(users!=null&&users.size()>0){
return true;
}
return false;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
在这里我必须要说明下通过spring将sessionfactory注入以后对于hibernate4来说只能用它的opensession方法,不能用getcurrentsession否则会报错,no current session。具体原因我也不是很清楚。
UserAction中我们需要通过自动注入来得到一个UserManager对象的引用,这就需要在配置文件中进行相应的配置,代码如下:
@Component("user")
@Scope("prototype")
public class UserAction extends ActionSupport{
private String username;
private String password;
private String password2;
private UserManager um;
@Override
public String execute() throws Exception {
User u = new User();
u.setUsername(username);
u.setPassword(password);
if(um.exists(u)){
return "fail";
}
um.add(u);
return "success";
}
public UserManager getUm() {
return um;
}
@Resource(name="userManager")
public void setUm(UserManager um) {
this.um = um;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword2() {
return password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
}
同时将UserManagerImpl中的代码加上相应的Annotation,下面来重点介绍下配置文件,首先在beans.xml中配一个sessionfactory的bean,代码如下:
<bean id="userDaoImpl"
class="com.bjsxt.registration.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
然后web.xml中对UserAction进行配置,代码如下:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
我们配置了一个监听器来对网页进行监听当发现UserAction被调用是就通过<context-param>中的<param-value>找到对应的beans.xml读取出其中对应的bean,注意要加入plugin包,这样它才能使struts2来通过spring得到相应的初试化,具体解释就是我们加入的plugin包下面有一个struts-plugin.xml里面的代码如下:
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.objectFactory" value="spring" />
ObjectFactory工厂对应的名字是spring即type对应的是spring的工厂StrutsSpringObjectFactory当需要的时候它就会到web.xml中去找对应的spring的那个工厂,而web.xml正好已经把beans.xml中对应的bean给读取出来了,所以这样就完成了初始化。最后别忘了把UserAction的范围设置为prototype,急@scope("prototype")。
下面介绍几个概念:
DTO:Data Transfer Object
VO: Value Object
当在action中要管理多个属性时,我们可以引入上面的概念,把这些属性用一个类封装起来,这样就不会造成程序的臃肿,UserAction中的代码如下:
public class UserAction extends ActionSupport implements ModelDriven{
private UserRegisterInfo info = new UserRegisterInfo();
private UserManager um;
@Override
public String execute() throws Exception {
User u = new User();
u.setUsername(info.getUsername());
u.setPassword(info.getPassword());
if(um.exists(u)){
return "fail";
}
um.add(u);
return "success";
}
public UserManager getUm() {
return um;
}
@Resource(name="userManager")
public void setUm(UserManager um) {
this.um = um;
}
public UserRegisterInfo getInfo() {
return info;
}
public void setInfo(UserRegisterInfo info) {
this.info = info;
}
public Object getModel() {
return info;
}
}
其中的UserRegisterInfo 对象来管理username,password,password2属性,在这里我们实现了一个ModelDriven接口的getModel方法,下面对它进行简单的介绍:
可以根据Action属性的不同将它分为两类:Field-Driven(属性驱动) Action和Model-Driven(模型模动) Action。
一、Field-Driven(属性驱动)Action,Action拥有自己的属性,这些属性一般是Java的基本类型。表单字段直接和Action的属性 对应。
二、实现了modelDriven接口可以在action中直接获得例如User对象,它会将Object getModel()取得的User放到ValueStack中。可以理解为将这个User的属性追加到Action中。它主要是作用是实现类似 Struts的FormBean功能。
在struts2中,提供了一种直接使用领域对象的方式,就是让action实现com.opensymphony.xwork2.ModelDriven接口,ModelDriven让你可以直接操作应用程序中的领域对象,允许你在web层和业务层使用相同的对象。
ModelDriven接口只有一个方法
public Object getModel() {return null;}
该方法返回一个用于接收用户输入数据的对象模型,在这个模型对象中的属性可以直接通过(属性名)userName来访问,而不需要使用(对象名.属 性名)user.userName这种格式来访问了,在action也不需要对对象提供getter和setter方法了,但是必须要在action中进 行new操作。