引言: Struts是Apache Software Foundation支持的Jakarta项目的一部分,它一个优秀的Web应用框架。该框架的主要体系设计师和开发者者是Craig R.McClanahan,Craig是Tomcat4的主设计师和Java Web Services Developer Pack实现包的主设计师,他领导着Sun的JavaServer Faces规范开发,同时也是Java EE平台的Web Layer Archiecture。
Hibernate是一个优秀的ORM中间件,它可以为任何一个需要访问关系数据库的Java应用服务,它的工作原理是通过文件把值对象和数据库表之间建立起一个映射关系,这样,我们只需要通过操作这些值对象和Hibernate提供的一些基本类,就可以达到使用数据库的目的。
下面我们通过使用这两种技术来实现一个简单的文章发布应用,在该应用中,我们可以浏览文章,可以发布文章。
step1: 在JBuilder中新建一个名为myArticles的工程,接着在工程中新建一个名为myArticlesWeb的Web Module,选中支持Struts1.1。
step2: 往工程中添加需要的jar文件,包括hibernate3.jar和hibernate下载包lib目录下的全部jar文件,以及MySQL数据库的驱动。
step3: 创建数据库myhibernate和表articles,创建的Schema如下:
CREATE DATABASE MYHIBERNATE;
USE MYHIBERNATE;
CREATE TABLE ARTICLES( id BIGINT NOT NULL, title VARCHAR(255) NOT NULL, content TEXT NOT NULL, writeDate DATE, PRIMARY KEY(id));
step4: 创建持久化类EntityArticle.java,代码如下:
package com.ouxingning.hibernate;
/** * <p>Title: articlesManage project</p> * * <p>Description: manage articles</p> * * <p>Copyright: Copyright (c) 2005</p> * * <p>Company: </p> * * @author ouxingning * @version 1.0 */import java.io.*;
import java.sql.Date;
public class EntityArticle implements Serializable {
private Long id;
private String title;
private String content;
private String remark;
private Date writeDate;
public EntityArticle() {
}
private void readObject(ObjectInputStream ois) throws IOException,
ClassNotFoundException {
ois.defaultReadObject();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
}
public void setId(Long id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setContent(String content) {
this.content = content;
}
public void setRemark(String remark) {
this.remark = remark;
}
public void setWriteDate(Date writeDate) {
this.writeDate = writeDate;
}
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public String getRemark() {
return remark;
}
public Date getWriteDate() {
return writeDate;
}}
step5: 创建对象-关系映射文件EntityArticle.hbm.xml,如下:
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping
package="com.ouxingning.hibernate">
<class name="EntityArticle" table="ARTICLES" lazy="false">
<comment>Article elements.</comment>
<id name="id">
<generator class="increment"/>
</id>
<property name="title" column="title" type="string" not-null="true"/>
<property name="content" column="content" type="text" not-null="true"/>
<property name="writeDate" column="writeDate" type="date"/>
</class></hibernate-mapping>
step6: 创建Hibernate配置文件hibernate.cfg.xml,如下:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>
<session-factory >
<property name="show_sql">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/myhibernate?useUnicode=true&characterEncoding=GBK</property>
<property name="connection.username">root</property>
<property name="connection.password">ouxingning</property>
<mapping resource="com/ouxingning/hibernate/EntityArticle.hbm.xml"/>
</session-factory></hibernate-configuration>
step7: 创建Hibernate的业务逻辑BusinessService.java,供Struts的Action调用,代码如下:
package com.ouxingning.hibernate;
/** * <p>Title: articlesManage project</p> * * <p>Description: manage articles</p> * * <p>Copyright: Copyright (c) 2005</p> * * <p>Company: </p> * * @author ouxingning * @version 1.0 */import org.hibernate.*;
import org.hibernate.cfg.*;import java.sql.Date;
import java.util.*;
import com.ouxingning.hibernate.EntityArticle;
public class BusinessService {
private static SessionFactory sessionFactory;
static {
//Create the SessionFactory
try {
sessionFactory = new Configuration().configure().
buildSessionFactory();
} catch (Exception ex) {
ex.printStackTrace();
}
}
//find all instances of EntityArticle
public List findAllArticles() {
List articles = new ArrayList();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
articles = session.createQuery("from EntityArticle").list();
tx.commit();
session.close();
return articles;
}
//save an persistent instance of EntityAnticle
public void saveArticle(EntityArticle article) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
EntityArticle myarticle = new EntityArticle();
myarticle.setTitle(article.getTitle());
myarticle.setContent(article.getContent());
myarticle.setWriteDate(article.getWriteDate());
myarticle.setRemark(article.getRemark());
session.save(myarticle);
tx.commit();
session.close();
}
//find an instance of EntityArticle by its indentifier property
public EntityArticle findArticleByID(Long id) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
EntityArticle ea = (EntityArticle) session.load(EntityArticle.class, id);
tx.commit();
session.close();
return ea;
}
//delete the instance of EntityArticle
public void deleteArticle(EntityArticle ea) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.delete(ea);
tx.commit();
session.close();
}
//update the instance of EntityArticle public void updateArticle(EntityArticle ea) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.update(ea);
tx.commit();
session.close();
}
public BusinessService() {
}
public static void main(String args[]) {
BusinessService bs = new BusinessService();
EntityArticle ea = new EntityArticle(); /*
ea.setTitle("欧兴宁'title");
ea.setContent("欧兴宁的内容");
ea.setRemark("欧兴宁的备注");
//change the type java.util.Date to java.sql.Date
java.util.Date ud = new java.util.Date();
ea.setWriteDate(new java.sql.Date(ud.getTime()));
bs.saveArticle(ea);
System.out.println("good");
List results = bs.findAllArticles();
for(int i=0;i<results.size();i++){
ea = (EntityArticle)results.get(i);
System.out.print(ea.getId() + "\t");
System.out.print(ea.getTitle() + "\t");
System.out.print(ea.getContent() + "\t");
System.out.println(ea.getWriteDate());
}*/ for (int i = 0; i < 9; i++) {
Long id = new Long(i);
ea = bs.findArticleByID(id);
System.out.print(ea.getId() + "::");
System.out.print(ea.getTitle() + "\t");
System.out.print(ea.getWriteDate() + "\t");
System.out.println(ea.getContent());
}
System.out.println("end");
}}
step8: 创建用于显示列表的表现层文件articleList.jsp,代码如下:
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles"%><%@taglib uri="/WEB-INF/struts-nested.tld" prefix="nested"%><%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%><%@taglib uri="/WEB-INF/struts-template.tld" prefix="template"%><%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%><%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><%@page contentType="text/html;
charset=GBK"%><%@page import="com.ouxingning.hibernate.*"%><%@page import="java.util.*"%><html:html locale="true"><head>
<meta http-equiv="Content-Type" content="text/html;
charset=gb2312"><title>文章列表</title>
<html:base/></head><body>
<table width="780" border="0" align="center">
<tr>
<td align="center" valign="middle">
<h1>文章列表</h1>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<hr size="1">
</td>
</tr>
<logic:iterate id="article" name="articles" type="com.ouxingning.hibernate.EntityArticle">
<tr> <td align="left" valign="middle" bgcolor="#FFFFFF">
<bean:write name="article" property="id"/>
、
<html:link forward="showArticle" paramId="articleID" paramName="article" paramProperty="id">
<bean:write name="article" property="title"/>
</html:link>
[
<bean:write name="article" property="writeDate"/>
]
</td>
</tr>
</logic:iterate>
</table></body></html:html>
step9: 创建用于显示每篇文章内容的表现层文件showArticle.jsp,代码如下:
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles"%><%@taglib uri="/WEB-INF/struts-nested.tld" prefix="nested"%><%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%><%@taglib uri="/WEB-INF/struts-template.tld" prefix="template"%><%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%><%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><%@page contentType="text/html; charset=GBK"%><%@page import="com.ouxingning.hibernate.*"%><%@page import="java.util.*"%><html:html locale="true"><head> <meta http-equiv="Content-Type" content="text/html;
charset=gb2312"><title><bean:write name="article" property="title"/></title>
<html:base/></head><body>
<table width="780" border="0" align="center">
<tr>
<td align="center" valign="middle">
<h1><bean:write name="article" property="title"/></h1>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<hr size="1">
</td>
</tr>
<tr>
<td align="left" valign="middle" bgcolor="#FFFFFF">
<bean:write name="article" property="content"/>
</td>
</tr>
<tr>
<td align="center" valign="middle">
<hr size="1">
</td>
</tr>
<tr>
<td align="right" valign="middle">
Created at: <bean:write name="article" property="writeDate"/>
</td>
</tr>
</table></body></html:html>
step10: 创建用于提交文章的表现层文件writeArticle.jsp,代码如下:
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles"%><%@taglib uri="/WEB-INF/struts-nested.tld" prefix="nested"%><%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%><%@taglib uri="/WEB-INF/struts-template.tld" prefix="template"%><%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%><%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><%@page contentType="text/html; charset=GBK"%><html:html locale="true"><head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>写文章</title> <html:base/></head><body>
<html:errors/> <html:form action="/writeArticleAction" method="post">
<table width="780" border="0" align="center">
<tr>
<td colspan="2" align="center" valign="middle">
<h1>写文章</h1>
</td>
</tr>
<tr>
<td colspan="2" align="center" valign="middle">
<hr size="1">
</td>
</tr>
<tr>
<td align="right" valign="middle">文章标题:</td>
<td align="left" valign="middle">
<html:text property="title" size="81"/>
</td>
</tr>
<tr>
<td align="right" valign="top">文章内容:</td>
<td align="left" valign="middle">
<html:textarea cols="80" rows="20" property="content"> </html:textarea>
</td>
</tr>
<tr align="center" valign="middle">
<td align="right" valign="top">
<html:submit value="发表文章" property="Submit"/>
</td>
<td align="left" valign="middle">
<html:reset value="清除内容" property="Reset"/>
</td>
</tr>
</table>
</html:form></body></html:html>
step11: 创建ArticleActionForm.java,代码如下:
package com.ouxingning.Struts;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionMapping;import javax.servlet.http.HttpServletRequest;import org.apache.struts.*;import org.apache.struts.action.*;public class ArticleActionForm extends ActionForm {
private String content;
private String title;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public ActionErrors validate(ActionMapping actionMapping,
HttpServletRequest httpServletRequest) {
ActionErrors errors = new ActionErrors();
if ((title == null) || (title.length() < 1)) {
errors.add("title", new ActionError("writeArticle.err.title"));
}
if ((content == null) || (content.length() < 1)) {
errors.add("content", new ActionError("writeArticle.err.content"));
}
return errors;
} public void reset(ActionMapping actionMapping,
HttpServletRequest servletRequest) {
content = null;
title = null;
}}
step12: 创建writeArticleAction.java,代码如下:
package com.ouxingning.Struts;import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.ActionForward;
import org.apache.struts.action.Action;import com.ouxingning.hibernate.*;
import com.ouxingning.Struts.*;public class WriteArticleAction extends Action {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
ArticleActionForm articleActionForm = (ArticleActionForm) actionForm;
BusinessService bs = new BusinessService();
EntityArticle ea = new EntityArticle();
ArticleActionForm aaf = (ArticleActionForm)actionForm;
ea.setTitle(aaf.getTitle());
ea.setContent(aaf.getContent());
//change java.util.Date to java.sql.Date
java.util.Date ud = new java.util.Date();
ea.setWriteDate(new java.sql.Date(ud.getTime()));
//persistant the instance of EntityArticle
bs.saveArticle(ea);
return actionMapping.findForward("success");
}}
step13: 创建ArticleListAction.java,代码如下:
package com.ouxingning.Struts;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.Action;import java.util.*;
import com.ouxingning.hibernate.*;
public class ArticleListAction extends Action {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
BusinessService bs = new BusinessService();
List articles = bs.findAllArticles();
servletRequest.setAttribute("articles",articles);
return actionMapping.findForward("showArticles");
}}
step14: 创建ShowArticleAction.java,代码如下:
package com.ouxingning.Struts;import org.apache.struts.action.ActionMapping;import org.apache.struts.action.ActionForm;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.ActionForward;import org.apache.struts.action.Action;import com.ouxingning.hibernate.*;public class ShowArticleAction extends Action {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
BusinessService bs = new BusinessService();
EntityArticle ea = new EntityArticle();
ea = bs.findArticleByID(new Long(servletRequest.getParameter("articleID")));
servletRequest.setAttribute("article", ea);
return actionMapping.findForward("showArticle");
}}
step15: 创建个名叫SetCharacterEncodingFilter.java的Filter用于处理中文乱码问题,代码如下:
package com.ouxingning.Struts;import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import java.util.*;public class SetCharacterEncodingFilter extends HttpServlet implements Filter { private FilterConfig filterConfig; //Handle the passed-in FilterConfig public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
//Process the request/response pair
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) {
try {
request.setCharacterEncoding("GBK");
filterChain.doFilter(request, response);
} catch (ServletException sx) {
filterConfig.getServletContext().log(sx.getMessage());
} catch (IOException iox) {
filterConfig.getServletContext().log(iox.getMessage());
}
}
//Clean up resources
public void destroy() {
}}
step16: JBuilder自动生成的web.xml文件,如下:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>myArticles</display-name> <jsp-config> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-template.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-template.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
</jsp-config>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>application</param-name>
<param-value>ApplicationResources</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern> </servlet-mapping> <filter>
<filter-name>setcharacterencodingfilter</filter-name>
<filter-class>com.ouxingning.Struts.SetCharacterEncodingFilter</filter-class>
</filter> <filter-mapping>
<filter-name>setcharacterencodingfilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<servlet>
step17: JBuilder自动生成的struts-config.xml文件,如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"><struts-config>
<form-beans>
<form-bean name="articleActionForm" type="com.ouxingning.Struts.ArticleActionForm" /> </form-beans> <global-forwards>
<forward contextRelative="true" name="articles" path="/articleListAction.do" redirect="true" />
<forward contextRelative="true" name="showArticle" path="/showArticleAction.do" /> </global-forwards> <action-mappings>
<action input="/pages/articleList.jsp" path="/articleListAction" scope="request" type="com.ouxingning.Struts.ArticleListAction">
<forward contextRelative="true" name="showArticles" path="/pages/articleList.jsp" redirect="false" />
</action>
<action input="/pages/writeArticle.jsp" name="articleActionForm" path="/writeArticleAction" scope="request" type="com.ouxingning.Struts.WriteArticleAction">
<forward name="success" path="/index.jsp" />
</action>
<action input="/pages/articleList.jsp" path="/showArticleAction" scope="request" type="com.ouxingning.Struts.ShowArticleAction">
<forward contextRelative="true" name="showArticle" path="/pages/showArticle.jsp" />
</action> </action-mappings></struts-config>
总结: 在这个简单的文章发布应用中,我们使用了Struts作为表现层框架,使用了Hibernate作为持久化层框架,大大增强的应用的可扩展性和可维护性。各位对Struts或Hibernate感兴趣的朋友可以继续扩展该应用,在扩展过程中,《Struts in Action》,《Hibernate in Action》以及Hibernate的文档都是很好的参考资料。