SSH的框架一度在JAVA企业应用中占有很高的比例,几年前也用SSH做过一些网站及应用服务接口相关的项目。最近在整理一些之前的工作,所以简单回顾一下。用下面的例子算是做个学习笔记吧。
1. 引言
每种框架都有其自身的优势和不足,这和框架本身的设计初衷以及后来的发展,包括社区支持等等各种因素相关。Anyway,现在越来越多的人认同Spring似乎提供了更好和更广的功能性选择。不过还是有一些因素,导致需要去学习或者使用Struts,比如:
1)你所在公司的一些老项目是使用Struts开发的,很不幸,你需要去维护他们
2)其他一些因素,你需要学习,比如架构选择的需要,或者和其他系统的对接等需要
3)或者你如果应聘一个架构师或者高级开发的岗位,常常有人会问你,讲讲struts 和 Spring的区别吧。。。
2. 设置基础环境
1)安装JDK,这是PATH
2)安装应用服务器,如Tomcat
3)安装构建工具,如 Maven
4)在IDE(如Eclipse或IDEA)的偏好设置中,设置应用服务器和构建工具的路径
5)设置示例程序所需的数据库,如
CREATE DATABASE `leedb`;
CREATE TABLE `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`description` varchar(512) NOT NULL,
`price` float NOT NULL,
PRIMARY KEY (`product_id`)
)
3. 使用构建工具添加相关依赖
1)创建一个 MAVEN web-app 类型项目
2)在 pom.xml 中添加如下内容
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.leelei</groupId>
<artifactId>SSHDemo</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>SSHDemo</name>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.1.6.RELEASE</org.springframework-version>
<org.strutsframework-version>2.3.20</org.strutsframework-version>
<org.hibernateframework-version>4.3.8.Final</org.hibernateframework-version>
<org.mysqlconnector-version>5.1.34</org.mysqlconnector-version>
</properties>
<dependencies>
<!-- Spring framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Struts2 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${org.strutsframework-version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${org.strutsframework-version}</version>
</dependency>
<!-- Hibernate ORM -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${org.hibernateframework-version}</version>
</dependency>
<!-- DBCP -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.0</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${org.mysqlconnector-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>webapp</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
4. 相关代码
1)Model和Mapping
package com.leelei.model;
public class Product {
private long id;
private String name;
private String description;
private float price;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
创建对应的Mapper文件, Product.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.leelei.model">
<class name="Product" table="PRODUCT">
<id name="id" column="PRODUCT_ID">
<generator class="native"/>
</id>
<property name="name" />
<property name="description" />
<property name="price" />
</class>
</hibernate-mapping>
2)DAO文件
创建package com.leelei.dao
package com.leelei.dao;
import java.util.List;
import com.leelei.model.Product;
public interface ProductDAO {
List<Product> list();
}
dao的实现文件
package com.leelei.dao;
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import com.leelei.model.Product;
public class ProductDAOImpl implements ProductDAO {
private SessionFactory sessionFactory;
public ProductDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@Transactional
public List<Product> list() {
@SuppressWarnings("unchecked")
List<Product> listProduct = (List<Product>)
sessionFactory.getCurrentSession().createCriteria(Product.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
return listProduct;
}
}
3)Action
package com.leelei.action;
import java.util.List;
import com.leelei.dao.ProductDAO;
import com.leelei.model.Product;
import com.opensymphony.xwork2.ActionSupport;
public class ListProductAction extends ActionSupport {
private ProductDAO productDAO;
private List<Product> listProduct;
public void setProductDAO(ProductDAO productDAO) {
this.productDAO = productDAO;
}
public String execute() {
listProduct = productDAO.list();
return SUCCESS;
}
public List<Product> getListProduct() {
return listProduct;
}
}
execute()调用ProductDAO(通过getListProduct())来获取产品信息列表以用于视图显示。Spring通过setter方法(setProductDAO())注入一个ProductDAO的实例。
4)创建视图文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Product List</title>
</head>
<body>
<div align="center">
<table width="80%" border="1" style="border-collapse: collapse;">
<tr>
<th>No</th>
<th>Product Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<s:iterator value="listProduct" status="stat">
<tr>
<td><s:property value="#stat.count" /></td>
<td><s:property value="name" /></td>
<td><s:property value="description" /></td>
<td><s:property value="price" /></td>
</tr>
</s:iterator>
</table>
</div>
</body>
</html>
5)配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>SSHDemo</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>DispatcherFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DispatcherFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
这里,我们将Struts配置成一个请求转发器,将Spring用作上下文监听器来管理Beans和依赖注入。
6)HIbernate配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping resource="com/leelei/model/Product.hbm.xml"/>
</session-factory>
</hibernate-configuration>
在这里简单地通过 dialect来链接MySQL,并告诉它指定的MAPPER文件
<?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">
<struts>
<package name="SSHDemo" extends="struts-default">
<action name="listProduct" class="listProductActionBean">
<result name="success">/WEB-INF/views/ProductList.jsp</result>
</action>
</package>
</struts>
定义一个动作匹配来处理 URL /listProduct 请求。注意动作类现在被指向一个Spring管理的名为 -listProductActionBean 的 Bean。我们也配置了SUCCESS视图指向ProductList.jsp 页面。
7)Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="listProductActionBean" class="com.leelei.action.ListProductAction">
<property name="productDAO" ref="productDAO" />
</bean>
<bean id="productDAO" class="com.leelei.dao.ProductDAOImpl">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/rest" />
<property name="username" value="root" />
<property name="password" value="#######" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
定义一个Struts Action : listProductActionBean, productDAO bean被声明和注入 这个Action。
productDAO需要一个SessionFactory,所以我们定义一个。SessionFactory需要一个DataSource,所以我们定义一个DS(包括一些链接数据的参数)
最后我们定义个事务管理器。
8)最终文件结构
5. 参考
http://www.codejava.net/frameworks/struts/struts-2-spring-4-hibernate-4-integration-tutorial-part-1-xml-configuration
根据以上文章翻译整理