Struts2,Spring,Hibernate是Java Web开发中最为常见的3种框架,掌握这3种框架是每个Java Web开发人员的基本功。
然而,很多初学者在集成这3个框架的时候,总是会遇到各种各样的问题。
大学期间,刚刚学习SSH的时候,也是如此。
当时,做了一个Demo性质的在线书店,现在分享给大家。
希望对初学者有所帮助。
CSDN下载地址(免积分):http://download.csdn.net/detail/fansunion/6345147
下载包内容
FansBookShopping.zip:项目源码,1个完整的Eclipse项目,可以直接导入到Eclipse中。
shopping.sql:数据库脚本,包含 数据库和表创建,以及数据。
项目结构.gif:项目结构截图
项目截图.gif项目运行效果图
项目结构
包简介
action:控制层,Struts2的Action,响应前端HTTP请求。
service:业务层,处理业务逻辑。
dao:数据访问层,数据库增删改查接口。
domain:领域实体。
util:工具类。
实体
Book:书籍,一本书,比如“《编写可读代码的艺术》”。
BookCategory:书籍分类,比如“管理”、“计算机”。
BookComment:书的评论。
Order:一个订单。
OrderItem:一个订单的一项。
User:用户。
UserRole:用户的角色。
实体虽然有7个,真正的实现却很简单,这并不是一个完整的在线书店项目。
整合说明
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>FansBookShopping</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <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>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!– 指定Struts2配置文件的DTD信息 –> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <!– Struts2配置文件的根元素 –> <struts> <!– Struts2的对象工厂为spring,Struts2和spring整合的关键部分 –> <constant name="struts.objectFactory" value="spring"></constant> <!– Struts2开发模式,开发过程设为true,可以获得更多异常信息,便于及时解决问题 –> <constant name="struts.devMode" value="true"></constant> <package name="bookShopping" namespace="" extends="struts-default"> <!– 导向注册页面的action,仅仅起到了转向的作用 –> <action name="prevRegister"> <result name="success">/WEB-INF/content/register.jsp</result> </action> <!– 导向登录页面的action,仅仅起到了转向的作用 –> <action name="prevLogin"> <result name="success">/WEB-INF/content/login.jsp</result> </action> <!– 处理用户注册,即增加一个用户 –> <action name="register" class="userAction" method="add"> <!– 如果注册成功,导向welcome.action –> <result name="success" type="redirectAction"> <param name="actionName">welcome</param> </result> </action> <!–处理用户登录,即检验数据库中是否有这个用户 –> <action name="checkLogin" class="userAction" method="checkLogin"> <!– 如果注册成功,导向welcome.action –> <result name="success" type="redirectAction"> <param name="actionName">welcome</param> </result> </action> <!– 首页 –> <action name="welcome" class="bookAction" method="welcome"> <result name="success">/WEB-INF/content/welcome.jsp</result> </action> <!– –> <!– 根据书的分类,初始化数据,然后显示数据 –> <action name="pageBooks" class="bookAction" method="initBooksByPageIndex"> <result name="success">/WEB-INF/content/bookshopping.jsp</result> </action> <!– 根据书的分类和当前分页书,初始化数据,然后显示数据 –> <action name="pageCategoryBooks" class="bookAction" method="initBooksByPageIndexAndCategory"> <result name="success">/WEB-INF/content/bookshopping.jsp</result> </action> <!– 增加订单项,加入到购物车 –> <action name="shoppingcart" class="orderAction" method="addOrderItem"> <result name="success">/WEB-INF/content/shoppingcart.jsp</result> </action> <!– 结算 –> <action name="pay" class="orderAction" method="pay"> <!– 结算成功,跳转到findOrder.action –> <result name="success" type="redirectAction"> <param name="actionName">findOrder</param> <param name="orderId">${orderId}</param> </result> </action> <!– 支付成功。显示刚刚的订单的信息 –> <action name="findOrder" class="orderAction" method="find"> <result name="success">/WEB-INF/content/paySuccess.jsp</result> </action> </package> </struts>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!– 指定Spring配置文件的Schema信息 –> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:property-placeholder location="classpath:jdbc.properties" /> <!–数据源 –> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${driverClass}" /> <property name="jdbcUrl" value="${jdbcUrl}" /> <property name="user" value="${user}" /> <property name="password" value="${password}" /> </bean> <!– sessionFactory –> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>cn/fansunion/bookshopping/domain/Book.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/BookCategory.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/BookComment.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/Order.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/OrderItem.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/User.hbm.xml</value> <value>cn/fansunion/bookshopping/domain/UserRole.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = true hibernate.format_sql = false <!– hibernate.hbm2ddl.auto = update –> </value> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"> </bean> <!– <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> –> <!– 基于注解的方式配置事务 –> <tx:annotation-driven transaction-manager="transactionManager" /> <!– 基于扫描的方式配置bean –> <context:component-scan base-package="cn.fansunion.bookshopping" /> </beans>
列表功能-代码举例说明
BookAction
// 根据书的分类和分页数初始化数据 public String initBooksByPageIndexAndCategory() throws ServiceException { //初始化所有书籍分类 bookCategories = bookService.findAllBookCategories(); books = bookService.findByPage(pageIndex, bookCategoryId); pageCounter = bookService.getPageCounter(); initPagination(); return SUCCESS; }
BookServiceImpl
public List<Book> findByPage(int pageIndex, long bookCategoryId) throws ServiceException { List<Book> books = null; try { LOG.info("Try to findByPage(int pageIndex, long bookCategoryId)."); String sql = "select * from book where book_category_id = ?"; Class<?> clazz = Book.class; int pageSize = WebConstants.BOOK_PAGE_SIZE; books = bookDao.findByPage(sql, clazz, bookCategoryId, pageIndex, pageSize); String sqlCounter = "select count(*) from book where book_category_id = ?"; pageCounter = bookDao.getPageCounter(sqlCounter, bookCategoryId); LOG.info("findByPage(int pageIndex, long bookCategoryId) successfully."); } catch (RuntimeException re) { LOG.error("findByPage(int pageIndex, long bookCategoryId) failed." + re); throw new ServiceException( "findByPage(int pageIndex, long bookCategoryId) failed.", re); } return books; }
单元测试-举例说明
@Test public void testAdd() { BookService bookService = (BookService) context .getBean("bookServiceImpl"); Book book = new Book(); book.setAuthor("fans"); book.setName("java"); book.setPress("中信出版社"); BookCategory bookCategory = new BookCategory(); bookCategory.setBookCategoryId(1); book.setBookCategory(bookCategory); // 增加书籍 bookService.add(book); Integer bookId = book.getBookId(); System.out.println(bookId); // 查找书籍 Book book2 = bookService.find(bookId); System.out.println(book); System.out.println(book2); // 断言 Assert.assertEquals(book, book2); // 删除书籍 bookService.delete(book); Book book3 = bookService.find(bookId); // 断言 Assert.assertNull(book3); }
友情提示
由于这是大学时的小项目,功能设计、代码实现、单元测试等很多地方有问题。
有兴趣的同学,自己完善不足之处。
本文重点是介绍如何集成SSH3大框架。