图解
【1】SSH整合-基本环境配置
开发环境:myeclipse6.0+tomcat6.0+struts2.0+hibernate3.1+spring2.0+MySQL5.0
【1】新建工程项目,右键myeclipse->添加hibernate支持,注意要将相应的jar添加到web-inf文件夹下,防止以后转以后找不到相应的包文件,暂不配置hibernate的DB,使用spring进行管理
【2】同样添加spring的支持,勾选spring中的web开发的jar包,spring会自动生成applicationContext.xml的配置文件,不创建sessionfactory,稍后自己创建
【3】添加struts2的包,因myeclipse6.0中还没有集成了struts2的配置,因此需要自己添加到lib文件夹,在src下创建struts.xml文件,此为struts2必须的配置文件
文件头如下所示:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- 并在web.xml下配置struts2的过滤器声明使用
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
同时加入spring的配置信息
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
此时可能发生spring和hibernate的冲突,因其导入了版本不同的包,具体的可通过搜索查询
新建Mysql的数据库,将其编码设置为utf-8,以便兼容不同的语言,此后新建的jsp页面也以utf-8为基本编码
至此,基本环境配置完毕,可将项目配置到tomcat中进行检测,正常启动说明配置成功。
【2】SSH整合-分层代码实现
接着开始进行编码
【1】新建javabean,以user类为模板,
- public class User {
- private Integer id;
- private String firstname;
- private String lastname;
- private int age; ……
- }
为每个属性生成get和set方法,这是spring要使用所必须的,以后要使用的类也一样
同时为此基本的Bean配置和编写此bean和数据库的映射文件,文件名为user.hbm.xml
内容如下:(hibernate具有反向工程映射功能,将数据库的实体映射为持久类以及相应配置文件和DAO类)
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="oa.sean.bean.User" table="users">
- <id name="id" type="java.lang.Integer" column="id">
- <generator class="increment"></generator>
- </id>
- <property name="firstname" type="string" column="firstname" length="50"></property>
- <property name="lastname" type="string" column="lastname" length="50"></property>
- <property name="age" type="java.lang.Integer" column="age" ></property>
- </class>
- </hibernate-mapping>
【2】为struts添加国际化标准
在src中新建struts.properties 内容为struts.custom.i18n.resources=globalMessages
同时也在相同目录下新建globalMessages-en.properties和globalMessages-zh.properties文件
以zh文件内容为例
firstname=/u59d3
lastname=/u540d
age=/u5e74/u9f84
这样在以后页面当中使用如果浏览器的语言是中文的话就可以以中文的方式进行显示,英文的话则按照en的配置文件进行显示
当然要修改相应的页面标签,如下
<s:textfield name="user.firstname" label="%{getText('firstname')}"></s:textfield>
【3】新建user的dao操作
创建一个user的接口
- public interface UserDAO {
- public void saveUser(User user);
- public void removeUser(User user);
- public User findUserById(Integer id);
- public List<User> findAllUsers();
- public void updateUser(User user);
- }
之后定义一个impl类来实现此接口中的方法
部分代码如下:
- public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
- @SuppressWarnings("unchecked")
- public List<User> findAllUsers() {
- //是类名,不是表名
- String hql="from User user order by user.id desc";
- return (List<User>)this.getHibernateTemplate().find(hql);
- }……
- }
可以使用hibernate中提供的方法来简化数据库的操作
【4】创建服务层代码
dao操作不能直接被action调用,要在中间添加服务层
新建一个service的接口
- public interface UserService {
- //action 和 dao之间要加入此服务层
- public List<User> findAll();
- public void save(User user);
- public void delete(User user);
- public User findById(Integer id);
- public void update(User user);
- }
与dao类似,实现此接口
- public class UserServiceImpl implements UserService {
- private UserDAO userDao;
- //要让spring进行注入要设置get和set方法
- public UserDAO getUserDao() {
- return userDao;
- }
- public void setUserDao(UserDAO userDao) {
- this.userDao = userDao;
- }
- ……
- }
在此编写中服务层代码只是简单调用dao方法
服务依赖于spring将其注入,再调用dao进行操作
【5】编写action方法中的execute方法
- public class SaveUserAction extends ActionSupport {
- private User user;
- private UserService userService;
- public UserService getUserService() {
- return userService;
- }
- public void setUserService(UserService userService) {
- this.userService = userService;
- }
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- @Override
- public String execute() throws Exception {
- this.userService.save(user);
- return SUCCESS;
- }
- }
在action中调用服务层的方法进行保存
【6】配置文件
struts.xml是控制前台控制的扭转
spring的则是bean之间的依赖关系和注入关系
- <struts>
- <package name="user" extends="struts-default">
- <action name="saveUser" class="saveUserAction">
- <result name="success" type="redirect">listUser.action</result>
- <result name="input">/save.jsp</result>
- </action>
- </package>
-
- </struts>
- <struts>
- <package name="user" extends="struts-default">
- <action name="saveUser" class="saveUserAction">
- <result name="success" type="redirect">listUser.action</result>
- <result name="input">/save.jsp</result>
- </action>
- </package>
- </struts>
【3】SSH整合-spring注入
【1】配置spring
在前面的基础上编写了DAO层,SERVICE层等的代码,现在需要通过spring的配置文件将各层连接并进行注入
首先先配置数据源
<!-- 数据源配置 -->
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
- <property name="url" value="jdbc:mysql://localhost:3306/oa"></property>
- <property name="username" value="root"></property>
- <property name="password" value="root"></property>
- <property name="maxActive" value="100"></property>
- <property name="maxIdle" value="30"></property>
- <property name="maxWait" value="500"></property>
- <property name="defaultAutoCommit" value="true"></property>
- </bean>
这也就是以前通过javabean等实现的连接数据库操作,spring是通过连接池进行数据库的连接的
接着配置与之相关的java类的关系
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource" ref="dataSource"></property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
- <prop key="hibernate.show_sql">true</prop>
- </props>
- </property>
- <property name="mappingResources">
- <list>
- <value>oa/sean/bean/User.hbm.xml</value>
- </list>
- </property>
- </bean>
将其注入到sessionfactory当中
整个过程就是这样,然后将sessionfactory注入到DAO,DAO再注入到action当中,实现了从数据库到jsp页面的一套流程
下面配置dao层和服务层
- <bean id="userDao" class="oa.sean.dao.impl.UserDAOImpl" scope="singleton">
- <property name="sessionFactory">
- <ref bean="sessionFactory"/>
- </property>
- </bean>
- <bean id="userService" class="oa.sean.service.impl.UserServiceImpl">
- <property name="userDao" ref="userDao"></property>
- </bean>
注意:dao层是没有状态的,因此将其配置成singleton,默认的也是使用此方法
最后是注入到action当中
注意spring的配置文件当中的名称要和struts当中定义的class一样
见红色所示:
- <bean id="userService" class="oa.sean.service.impl.UserServiceImpl">
- <property name="userDao" ref="userDao"></property>
- </bean>
- <!-- 所有的action要设置成prototype性质的,可每次访问生成一个实例,否则默认为singleton,只生成一个实例 -->
- <bean id="saveUserAction" class="oa.sean.action.user.SaveUserAction" scope="prototype">
- <property name="userService" ref="userService"></property>
- </bean>
- <bean id="listUserAction" class="oa.sean.action.user.ListUserAction" scope="prototype">
- <property name="userService" ref="userService"></property>
- </bean>
- <bean id="removeUserAction" class="oa.sean.action.user.RemoveUserAction" scope="prototype">
- <property name="service" ref="userService"></property>
- </bean>
- <bean id="updatePUserAction" class="oa.sean.action.user.UpdatePUserAction" scope="prototype">
- <property name="service" ref="userService"></property>
- </bean>
- <bean id="updateUserAction" class="oa.sean.action.user.UpdateUserAction" scope="prototype">
- <property name="service" ref="userService"></property>
- </bean>
- <!-- 有状态的用prototype类型,没状态的用singleton,区分一个action是否有状态,是否有相互区分的属性 -->
- <bean id="generateExcelAction" class="oa.sean.action.user.GenerateExcelAction" >
- <property name="service" ref="userService"></property>
- </bean>
此时简单的一个SSH就基本完成了
加上前台的页面就可以看到结果了
【4】SSH整合-加入struts校验框架
struts2为我们提供了一套校验的框架,只要使用即可
在action下新建同名文件: XXXAction-validation.xml ,往当中写入相应的校验信息,struts在页面提交的时候会自动在此文件当中去寻找相应的信息进行匹配
一个文件范例如下:SaveUserAction-validation.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
- <validators>
- <field name="user">
- <field-validator type="visitor">
- <param name="context">user</param>
- <param name="appendPrefix">true</param>
- <message>user's </message>
- </field-validator>
- </field>
- </validators>
此文件中只配置了采用visitor的类型进行校验,如出现错误信息会在信息前添加user‘s 字段
然后在User类的文件夹下创建关于User的具体校验信息
范例如下:User.hbm.xml,注意文件名一定要符合规范
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="oa.sean.bean.User" table="users">
- <id name="id" type="java.lang.Integer" column="id">
- <generator class="increment"></generator>
- </id>
- <property name="firstname" type="string" column="firstname" length="50"></property>
- <property name="lastname" type="string" column="lastname" length="50"></property>
- <property name="age" type="java.lang.Integer" column="age" ></property>
- </class>
- </hibernate-mapping>
这里在强调一点:对于有状态的Action在配置的时候要将其配置成prototype,否则将会出现系列问题
典型的就是配置好之后第一次输入错误将正确的返回错误信息,第二次依然返回错误信息而无法提交
因为action默认的是singleton类型,所有只生成一个实例,而错误信息只要第一次产生便会存在
就算第二次输入的是正确的信息,依然有第一次的fielderror存在,因此表单仍然不会提交
至此,能为表单提供一个符合自己要求的校验框架了。