SSH框架指的是Struts,Hibernate和Spring三个框架的结合。Struts使用的是2.1版本,它作为MVC的框架,Action拦截用户所有请求,然后进行处理和转发。Spring使用的是3.0版本,它提供了作为业务逻辑组件的IoC容器和DAO组件工厂,负责生成和管理这些实例。借助于Spring的依赖注入,各个组件以松藕的方式组合在一起,组件间的依赖通过Spring的依赖注入来管理。Hibernate使用的是3.3版本,作为OORM框架进行使用,简化了数据库的访问。系统具体分层为:表现层(JSP)——>Web层(Struts)——>业务逻辑层(Service)——>DAO——>持久层(Hibernate)——>数据库。
1. 添加Struts框架
选择类库的时候需要选择Struts2 Spring类库,这样就可以让Spring管理Struts中的组件了。由于还没有导入Spring框架,此时编译是不会成功的。
Web.xml中的配置如下:
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
filter-mapping属性声明了拦截器需要拦截的格式(默认是后缀是action),也就是说所有.action可以被Struts处理。使用Struts标签也需要可以被Struts拦截。想要所有页面都被拦截,可以改为/*。
我们还需要在struts.xml配置:
<constant name="struts.objectFactory"value="spring"/>
2. 添加Spring框架
添加时,需要选择AOP,Core,web的类库,3.0以后的版本,会将配置文件放在src目录下,src目录下的东西会生成在WEB-INF\classes的文件夹下面。此时我们配置的时候需要特别声明Spring配置文件的位置。
Web.xml中的配置如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
3. 添加Hibernate框架
MyEclipse自带有MyEclipse Database Explorer,可以对数据源进行配置。我们首先配置了数据源。然后添加Hibernate框架。配置时,需要选择Spring的applicationContext.xml作为Hibernate的数据源配置文件。
选择数据源,本次的测试数据库为admin,包含id,用户名和密码等字段。
applicationContext.xml自动生成了如下的配置:
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
<propertyname="driverClassName"value="com.mysql.jdbc.Driver">
</property>
<propertyname="url"value="jdbc:mysql://10.13.112.112:3306/onlinexam">
</property>
<propertyname="username"value="root"></property>
<propertyname="password"value="123456"></property>
</bean>
<beanid="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<propertyname="dataSource">
<refbean="dataSource"/>
</property>
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>
最后需要通过MyEclipse Database Explorer做Hibernate Reverse Engineering就可以了。ID生成方式选择Native就好了。
4. Spring+Hiberate整合
项目的整体解决方案中,应该包含如下几个包:model包含数据持久层的映射文件和POJO文件;DAO包含数据库的操作接口;DAOImpl包含数据库操作的具体类;Service包含业务逻辑的接口;ServiceImpl包含业务逻辑的具体类。现在编写DAO,Service和ServiceImpl的内容。(其他内容Hibernate已自动生成,生成到model中,注意实现类必须继承接口)
public interface AdminDAOInterface {
public AdminfindById(Integer id);
public ListfindByUsername(Object username);
public void save(Admin user);}
public interfaceAdminServiceInterface {
public AdmingetUserById(Integer id);
public AdmingetUserByUsername(String username);
public void addUser(Adminuser);}
public class AdminService implementsAdminServiceInterface {
private AdminDAOInterfaceuserDAO;
public void addUser(Admin user){
userDAO.save(user);}
public AdmingetUserById(Integer id) {
returnuserDAO.findById(id);}
public AdmingetUserByUsername(String username) {
List list = userDAO.findByUsername(username);
if (list.size() == 0) {
return null;
} else {
return (Admin)list.get(0);}}
public AdminDAOInterfacegetUserDAO() {
returnuserDAO;}
public voidsetUserDAO(AdminDAOInterface userDAO) {
this.userDAO = userDAO;}
}
applicationContext.xml配置如下:
<beanid="AdminDAO"class="daoimpl.AdminDAO">
<propertyname="sessionFactory">
<refbean="sessionFactory"/>
</property>
</bean>
<beanname="userService"class="serviceimpl.AdminService">
<propertyname="userDAO">
<refbean="AdminDAO"/></property>
</bean>
5. Spring+Struts整合
项目解决方案中,还有两个包:action存放struts处理程序,interceptor存放拦截器,例如验证用户是否已经登录等。
public class LoginAction extends ActionSupport {
privateAdminServiceInterfaceserviceAdmin;
private Stringusername;
private Stringpassword;
//省略get和set方法
publicAdminServiceInterface getServiceAdmin() {
returnserviceAdmin;}
public String execute() {
Admin user=serviceAdmin.getUserByUsername(username);
if(user==null){
ActionContext.getContext().put("tip","用户不存在!");
return"ERROR";}
else{
if(this.password.equals(user.getAdmPass())){
ActionContext.getContext().getSession().put("usr",username);
return"SUCCESS";}
else{
ActionContext.getContext().put("tip","密码错误!");
return"ERROR";}}}}
public class checkLoginInterceptorextends AbstractInterceptor{
public Stringintercept(ActionInvocation arg0)throws Exception {
LoginAction act =(LoginAction)arg0.getAction();
String username = act.getUsername();
if(username!=null&&username.length()>0){
return arg0.invoke();}
else{
arg0.getInvocationContext().put("tip2","不能为空");
return"ERROR";}}}
对于Struts中的Action,我们希望通过Spring来管理,所有需要在配置文件中特别声明。struts.xml配置使用spring进行管理,对于action采用拦截器来进行验证,防止用户输入空字符串。
struts.xml配置如下:
<struts>
<constantname="struts.objectFactory"value="spring"/>
<packagename="UserOperate"namespace="/User"extends="struts-default">
<interceptors>
<interceptorname="checkLogin"class="checkLoginInterceptor"/>
</interceptors>
<actionname="login"class="LoginAction">
<resultname="SUCCESS">/Success.jsp</result>
<resultname="ERROR">/index.jsp</result>
<interceptor-refname="defaultStack"/>
<interceptor-refname="checkLogin"/>
</action></package>
</struts>
applicationContext.xml添加:
<beanid="AdminDAO"class="daoimpl.AdminDAO">
<propertyname="sessionFactory">
<refbean="sessionFactory"/>
</property>
</bean>
<beanname="AdminService"class="serviceimpl.AdminService">
<propertyname="userDAO">
<refbean="AdminDAO"/></property>
</bean>
<beanname="LoginAction"class="action.LoginAction">
<propertyname="serviceAdmin">
<refbean="AdminService"/></property>
</bean>
<beanname="checkLoginInterceptor"class="interceptor.checkLoginInterceptor">
</bean>
6. 页面整合
在页面编写form,提交请求。提交的地址需要加上命名空间。对于action与jsp之间的传值,一般可以采用request.getAttribute和${}这两种。
<body>
<%if(request.getAttribute("tip")!=null ) out.print(request.getAttribute("tip").toString());%>
<formaction="User/login.action">
用户名称:<inputname="username"/><label>${tip2}</label><br>
用户密码:<inputname="password"/><br>
<inputtype="submit"value="登陆"/></form>
</body>
注意事项
1. Myeclipse整合框架功能时,可能会出现重复的包,或者同一个包的不同版本。例如antrl包,在struts和spring中都有包含。所以建议将包放在lib下面进行管理,对于重复的包需要进行删除。
2. 整合时,经常会找不到applicationContext.xml文件,我们可以在Web.xml中指定它的路径。
3. 在编写类的时候,要尽量使用依赖注入的方法,来提高解耦能力。由于hibernate交给spring管理,使用dao时,必须采用依赖注入的方法。