国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

論壇系統(Spring+Struts+Hibernate)

2019-11-08 02:31:51
字體:
來源:轉載
供稿:網友

論壇系統(基于SSH實現)

學web后臺開發已經有一段時間了,是時候做一點小總結。前段時間學習了一個小項目——論壇系統,是基于SPRing+Struts1+Hibernate框架開發的,雖然Struts1框架已逐漸比較少人用了,但作為初學者我覺得還是有必要了解一下。在實現完這個小系統后,我想把它改成基于Struts2實現的,畢竟Struts2比Struts1優秀得多。但了解到目前很多企業公司都采用了Spring+SpringMVC+Mybatis的組合框架,所以后來我把這個系統改成了基于Spring+SpringMVC+Mybatis實現的,SSM比SSH好就不用我多說了。下面先介紹基于SSH實現的,想看基于SSM實現的可直接看下一篇文章。

整個工程目錄以及數據庫表如下圖:

          

代碼下載

運行效果:

界面雖然丑了點,但我們這里只專注于后臺開發,界面就交給前端吧!微笑下面UI的代碼就不貼出來了,自己下載吧。

1、系統功能模塊

本系統包括5個模塊:用戶模塊、版面類型模塊、版面模塊、帖子模塊和回帖模塊。

用戶模塊:包括用戶的注冊、登錄、注銷、以及查看用戶資料等功能。發表帖子、發表回帖、設置版主等都需要用到用戶信息。注冊時將記錄用戶的注冊ip、注冊時間等,登錄時將記錄用戶的登錄IP、登錄時間等。版面類別模塊:本系統為二級結構,即先創建版面類別,然后才創建版面。本模塊包括創建版面類別,列出所有的類別、首頁等。首頁將列出所有的版面類別、各類別下對應的版面、帖子總數、回帖總數、最后發表的帖子或者回復、版主等。

版面模塊:包括創建版面、設置版主,列出所有本版的帖子等。帖子列表包括帖子標題、作者、發表時間、回帖數、人氣、最后回復人、最后回復時間等。

帖子模塊 :包括發表帖子、瀏覽帖子等。發表帖子時記錄發表帖子的IP等;瀏覽帖子時分頁列出所有的回帖,并更新帖子的人氣(瀏覽次數)等。

回帖模塊:包括發表回帖等。

2、數據庫設計

實體類使用Hibernate的注解的方式配置,數據庫表結構由實體類決定,DDL語句由Hibernate自動生成。本系統包括5個實體類:Person(用戶)、Category(版面類型)、Board(版面)、Thread(帖子)、Reply(回帖)。所有實體類都繼承自BaseBean,BaseBean中定義了主鍵id、樂觀鎖鍵version、刪除標志位deleted、創建日期dateCreated等基本字段。各實體類之間存在著一對一、一對多、多對多等關系,實體類關系圖如下圖:

2.1、BaseBean基類代碼

BaseBean基類代碼以及Hibernate配置如下(getter、setter方法略,下同):注意:實體類中的父類要使用@MappedSuperclass
package bean;@MappedSuperclass						//實體類父類public class BaseBean {	@Id	@GeneratedValue(strategy = GenerationType.AUTO)	private Integer id;	@Version							//版本列,hibernate自動維護該列	private Integer version;	private boolean deleted;	@Temporal(value = TemporalType.TIMESTAMP)	private Date dateCreated;}

2.2、Person類代碼

Person類為用戶信息,屬性boardsAdministrated代表該Person管理的版面,也就是版主。一個版面可以有多個版主,一個版主也可以管理多個版面,所以Person與Board是多對多的關系。
package bean;@Entity@Tablepublic class Person extends BaseBean {	private String account;	private String passWord;	private String sex;	private String name;	private String birthday;	private String email;	private String ipCreated;	@Temporal(value = TemporalType.TIMESTAMP)	private Date dateLastActived;	private String ipLastActived;	@ManyToMany(mappedBy = "administrators")	private Set<Board> boardsAdministrated = new HashSet<Board>();}

2.3、Category類代碼

Category類為版面類型
package bean;@Entity@Table@org.hibernate.annotations.Entitypublic class Category extends BaseBean {	private String name;	@OneToMany(mappedBy = "category")	private List<Board> boards = new ArrayList<Board>();}

2.4、Board類代碼

Board類代表版面,Board有兩個一對多的屬性lastThread與lastReply,以及一個多對多的屬性administrators。lastThread和lastReply分別保存最后發表的帖子及回帖。
package bean;@Entity@Tablepublic class Board extends BaseBean {	@ManyToOne	@JoinColumn(name = "category_id")	private Category category;	private String name;	private String description;	private int threadCount;	private int replyCount;	@ManyToOne	@JoinColumn(name = "last_reply_id")	private Reply lastReply;	@ManyToOne	@JoinColumn(name = "last_thread_id")	private Thread lastThread;	@ManyToMany(cascade = CascadeType.ALL)	@JoinTable(name = "board_administrator", joinColumns = { @JoinColumn(name = "board_id") }, inverseJoinColumns = { @JoinColumn(name = "person_id") })	private Set<Person> administrators = new HashSet<Person>();}

2.5、Thread類代碼

Thread類代表帖子,其中內容比較大,因此配置為延遲加載。
package bean;@Entity@Table@org.hibernate.annotations.Entitypublic class Thread extends BaseBean {	@ManyToOne	@JoinColumn(name = "board_id")	private Board board;	private String title;	@Basic(fetch = FetchType.LAZY)	@Column(columnDefinition="longtext")	private String content;	@ManyToOne	@JoinColumn(name = "author_id")	private Person author;	private String ipCreated;	private int hit;	@ManyToOne	@JoinColumn(name = "author_last_replied_id")	private Person authorLastReplied;	@Temporal(TemporalType.TIMESTAMP)	private Date dateLastReplied;	private boolean readonly;	private boolean topped;	private int replyCount;}

2.6、Reply類代碼

Reply代表回帖
package bean;@Entity@Table@org.hibernate.annotations.Entitypublic class Reply extends BaseBean {	@ManyToOne	@JoinColumn(name = "thread_id")	private Thread thread;	private String title;	@Basic(fetch = FetchType.LAZY)	private String content;	@ManyToOne	@JoinColumn(name = "author_id")	private Person author;	private int floor;	private String ipCreated;}

2.7、數據庫與Hibernate配置

在配置前先在MySQL中創建一個名為forum的數據庫,Hibernate配置在Spring的配置文件applicationContext.xml中,由Spring管理,采用hbm2ddl策略為update,啟動時會自動生成對應的表。
<?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:p="http://www.springframework.org/schema/p"	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"		destroy-method="close">	<!-- 定義數據源 -->		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>		<property name="url"			value="jdbc:mysql://localhost:3306/forum?characterEncoding=UTF-8"></property>		<property name="username" value="root"></property>		<property name="password" value="5845201314"></property>	</bean>	<bean id="sessionFactory"		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"		destroy-method="destroy">					<!-- SessionFactory實現類 -->		<property name="dataSource" ref="dataSource"></property>		<property name="annotatedClasses">		<!-- 配置實體類 -->			<list>				<value>bean.Board</value>				<value>bean.Category</value>				<value>bean.Person</value>				<value>bean.Reply</value>				<value>bean.Thread</value>			</list>		</property>		<property name="hibernateProperties">		<!-- Hibernate屬性 -->			<props>				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>				<prop key="hibernate.show_sql">true</prop>				<prop key="hibernate.hbm2ddl.auto">update</prop>				<prop key="hibernate.current_session_context_class">thread</prop>			</props>		</property>	</bean>	<bean id="hibernateTransactionmanager"		class="org.springframework.orm.hibernate3.HibernateTransactionManager">	<!-- Hibernate事務管理器 -->		<property name="sessionFactory" ref="sessionFactory"></property>	</bean>	<bean id="hibernateTransactionAttributeSource"		class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">	<!-- 事務管理規則 -->		<property name="properties">	<!-- 具有事務管理的方法名 -->			<props>				<prop key="*">PROPAGATION_REQUIRED</prop>	<!-- 所有方法都加事務 -->			</props>		</property>	</bean>		......</beans>

3、DAO層設計

DAO層負責與數據庫打交道,它把java Bean分拆成SQL語句并執行。個人覺得在ORM框架的基礎上再封裝一個DAO會更加方便。

3.1、IDAO代碼

由于Hibernate能操作所有的實體類,因此只定義一個DAO層即可。遵循接口編程原則,IDAO接口定義了最基本的DAO操作,同時也引入泛型,方便實現不同的實體類。
package dao;public interface IDao<T> {	public T find(Class<T> clazz, int id);	public void create(T baseBean);	public void save(T baseBean);	public void delete(T baseBean);		public List<T> list(String hql);	public int getTotalCount(String hql, Object... params);	public List<T> list(String hql, int firstResult, int maxSize,			Object... params);	public Query createQuery(String hql);}

3.2、DaoImpl代碼

DaoImpl繼承了Spring提供的HibernateDaoSupport類,該類主要提供兩個方法:public final HibernateTemplate getHibernateTemplate();public final void setSessionFactory(SessionFactory sessionFactory);其中setSessionFactory方法接收來自Spring的依賴注入,接收了配置在Spring的SessionFactory實例,getHibernateTemplate方法用來利用該實例生成Session,再生成HibernateTemplate來完成數據庫的訪問。
package dao;public class DaoImpl<T> extends HibernateDaoSupport implements IDao<T> {	@SuppressWarnings("unchecked")	public T find(Class<T> clazz, int id) {		return (T) getHibernateTemplate().get(clazz, id);	}	public void create(T baseBean) {		getHibernateTemplate().persist(baseBean);	}	public Query createQuery(String hql) {		return getSession().createQuery(hql);	}	public void delete(T baseBean) {		getHibernateTemplate().delete(baseBean);	}	@SuppressWarnings("unchecked")	public List<T> list(String hql) {		return getHibernateTemplate().find(hql);	}	public int getTotalCount(String hql, Object... params) {		Query query = createQuery(hql);		for (int i = 0; params != null && i < params.length; i++)			query.setParameter(i + 1, params[i]);		Object obj = createQuery(hql).uniqueResult();		return ((Long) obj).intValue();	}	@SuppressWarnings("unchecked")	public List<T> list(String hql, int firstResult, int maxResults,Object... params) {		Query query = createQuery(hql);		for (int i = 0; params != null && i < params.length; i++)			query.setParameter(i + 1, params[i]);		List<T> list = createQuery(hql).setFirstResult(firstResult).setMaxResults(maxResults).list();		return list;	}	public void save(T baseBean) {		getHibernateTemplate().save(baseBean);	}}

4、Service層設計

業務代碼集中在Service層,Action中調用Service完成業務邏輯,Service調用DAO完成數據存取。

4.1、IService接口

IService接口是所有Service的基類,定義了最基本的Service層方法。
package Service;public interface IService<T> {	public T find(Class<T> clazz, int id);	public void create(T baseBean);	public void save(T baseBean);	public void delete(T baseBean);	public List<T> list(String hql);	public int getTotalCount(String hql, Object... params);	public List<T> list(String hql, int firstResult, int maxSize,			Object... params);}

4.2、ServiceImpl實現

ServiceImpl實現了IService接口的方法,由于各個實體類的create()方法有不同的業務邏輯,因此create()方法定義為abstract的,有各自的Service單獨實現。由于含有抽象方法,類必須是抽象類!IDAO對象將由Spring通過IoC注射進來。
package Service;public abstract  class ServiceImpl<T extends BaseBean> implements IService<T> {	protected IDao<T> dao;	public IDao<T> getDao() {		return dao;	}	public void setDao(IDao<T> dao) {		this.dao = dao;	}	public T find(Class<T> clazz, int id) {		return dao.find(clazz, id);	}	public abstract void create(T baseBean);	public void delete(T baseBean) {		baseBean.setDeleted(true);		dao.save(baseBean);	}	public int getTotalCount(String hql, Object... params) {		return dao.getTotalCount(hql, params);	}	public void save(T baseBean) {		dao.save(baseBean);	}	public List<T> list(String hql) {		return dao.list(hql);	}	public List<T> list(String hql, int firstResult, int maxSize,			Object... params) {		return dao.list(hql, firstResult, maxSize, params);	}}

5、Action層設計

為了便于統一風格,統一控制,所有Action都繼承自ForumAction基類,所有的ActionForm都繼承自ForumForm基類。

5.1、ForumForm基類

ForumForm類繼承了Struts的ActionForm,封裝了action、title屬性,action用于區分不同的執行方式,title代表頁面的標題。
package form;public class ForumForm extends ActionForm {	private String action;	private String title;	public String getAction() {		return action;	}	public void setAction(String action) {		this.action = action;	}	public String getTitle() {		return title;	}	public void setTitle(String title) {		this.title = title;	}}

5.2、ForumAction基類

ForumAction類繼承了DispatchAction分發器,使用Action作為分發器的參數。各模塊的Action需要繼承該類,并實現各自的list()方法。
package action;public abstract class ForumAction extends DispatchAction {	protected Log log = LogFactory.getLog(getClass());	@Override	public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {		ForumForm forumForm = (ForumForm) form;				forumForm.setTitle("輕量級 Java EE 論壇程序");		System.out.println("execute  action:"+forumForm.getAction());		if (forumForm.getAction() == null|| forumForm.getAction().trim().length() == 0) {			return this.list(mapping, form, request, response);		}		return super.execute(mapping, form, request, response);	}	public abstract ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception;}

6、用戶模塊

6.1、IPersonService接口

IPersonService接口繼承IService接口,還需要定義自己單獨的方法。
package Service;public interface IPersonService<T extends Person> extends IService<T> {	/** 根據帳號查找用戶 */	public T findPersonByAccount(String account);	/** 根據帳號、密碼查找用戶 */	public T getPerson(String account, String password);}

6.2、PersonServiceImpl實現

PersonServiceImpl實現IPersonService接口,還需要實現自己的方法,創建用戶時,密碼需要經過加密后才保存到數據庫,md5工具類可下載源代碼查看。
package Service;public class PersonServiceImpl<T extends Person> extends ServiceImpl<T> implements IPersonService<T> {	@SuppressWarnings("unchecked")	@Override	public T findPersonByAccount(String account) {		List<T> person = this.getDao().createQuery(" select p from Person p "+ " where lower(p.account) = lower(:account) and deleted = false ")		.setParameter("account", account.trim()).list();		if (person.size() > 0)			return person.get(0);		return null;	}	@SuppressWarnings("unchecked")	@Override	public T getPerson(String account, String password) {		List<T> list = this.getDao().createQuery(" select p from Person p where p.account = :account "+ " and p.password = :password and p.deleted = false ")				.setParameter("account", account).setParameter("password",MD5Util.calc(password)).list();		if (list.size() > 0)			return list.get(0);		return null;	}	@Override	public void create(T person) {		if (findPersonByAccount(person.getAccount()) != null) 			throw new RuntimeException("帳號 " + person.getAccount() + " 已經存在。");		person.setPassword(MD5Util.calc(person.getPassword()));		this.getDao().create(person);	}}

6.3、PersonForm代碼

PersonForm還擁有person和password屬性,省略set和get方法
package form;public class PersonForm extends ForumForm {	private Person person = new Person();	private String password;	public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {		return null;	}	public void reset(ActionMapping mapping, HttpServletRequest request) {	}}

6.4、PersonAction代碼——用戶

PersonAction完成用戶模塊的注冊、登錄、注銷、查看用戶資料等。先看注冊相關代碼。personService對象將由Spring注射進來,注冊時會把用戶的id以及account保存到Session中,方便下次登錄時不需要進入登錄界面。
package action;public class PersonAction extends ForumAction {	private IPersonService<Person> personService;	//默認方法 返回到注冊頁面	public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		return this.initAdd(mapping, form, request, response);	}	public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("用戶注冊");		return mapping.findForward("add");	}	public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("用戶注冊");		Person person = personForm.getPerson();		person.setIpCreated(request.getRemoteAddr());		person.setIpLastActived(request.getRemoteAddr());		person.setDateCreated(new Date());		person.setDateLastActived(new Date());		if (person.getAccount() == null|| person.getAccount().trim().length() == 0) {			request.setAttribute("message", "請輸入帳號");			return this.initAdd(mapping, form, request, response);		}		if (person.getPassword() == null|| person.getPassword().trim().length() == 0|| !person.getPassword().equals(personForm.getPassword())) {			request.setAttribute("message", "密碼不一致");			return this.initAdd(mapping, form, request, response);		}		try {			personService.create(person);			PersonUtil.setPersonInf(request, response, person);			request.setAttribute("message", "注冊成功");			return new ActionForward("success", "/jsp/person/success.jsp",false);		} catch (Exception e) {			request.setAttribute("message", "注冊失敗,原因:" + e.getMessage());			return this.initAdd(mapping, form, request, response);		}	}	public IPersonService<Person> getPersonService() {		return personService;	}	public void setPersonService(IPersonService<Person> personService) {		this.personService = personService;	}}

6.5、PersonAction配置

在struts-config.xml中需要添加PersonAction的配置代碼,并且必須配置了controller后,Spring才能管理Action。之后幾個模塊的配置類似如下,就不再介紹了,攔截器與異常捕捉代碼,可下載查看。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config>  <form-beans >  	<form-bean name="personForm" type="form.PersonForm"></form-bean>  </form-beans>    <global-exceptions>  	<exception key="login" type="java.lang.Exception" handler="exception.ForumExceptionHandler"></exception>  </global-exceptions>    <global-forwards />    <action-mappings>  	<action attribute="personForm"   		path="/person"  		name="personForm"  		input="/jsp/person/listPerson.jsp"  		scope="request"  		parameter="action"  		type="action.PersonAction">				<!-- DispatchAction是通過請求參數來選擇方法 -->  		<forward name="add" path="/jsp/person/addPerson.jsp"></forward>  		<forward name="list" path="/jsp/person/listPerson.jsp"></forward>  	</action>  </action-mappings>    <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"></controller>	<!-- 把Struts的Action交給Spring代理 -->    <message-resources parameter="com.yourcompany.struts.ApplicationResources" /></struts-config>配置applicationContext.xml文件
<?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:p="http://www.springframework.org/schema/p"	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">	//結合前面代碼	<bean id="dao" class="dao.DaoImpl">		<property name="sessionFactory" ref="sessionFactory"></property>	</bean>	<bean id="personService"		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">	<!-- 事務工廠代理類 -->		<property name="transactionManager" ref="hibernateTransactionmanager"></property>		<property name="target">	<!-- 被管理的對象,匿名Bean -->			<bean class="Service.PersonServiceImpl">				<property name="dao" ref="dao"></property>			</bean>		</property>		<property name="transactionAttributeSource" ref="hibernateTransactionAttributeSource"></property>	</bean>	<bean id="loginInterceptor"		class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">	<!-- 方法前攔截器 -->		<property name="advice">			<bean class="interceptor.LoginInterceptor" />		</property>		<property name="mappedName" value="*"></property>	</bean>	<bean name="/person" class="org.springframework.aop.framework.ProxyFactoryBean">		<property name="interceptorNames">			<list>				<value>loginInterceptor</value>			</list>		</property>		<!-- 被攔截的對象 -->		<property name="target">			<bean class="action.PersonAction">				<property name="personService" ref="personService"></property>			</bean>		</property>	</bean></beans>注冊界面的效果如下:

6.6、PersonAction代碼——實現用戶登錄

package action;public class PersonAction extends ForumAction {	private IPersonService<Person> personService;	//結合前面相關代碼	public ActionForward initLogin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("用戶登錄");		return new ActionForward("login", "/jsp/person/login.jsp", false);	}	public ActionForward login(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("用戶登錄");		Person person = personService.getPerson(personForm.getPerson().getAccount(), personForm.getPerson().getPassword());		if (person == null)			throw new AccountException("用戶名密碼錯誤");		PersonUtil.setPersonInf(request, response, person);		person.setIpLastActived(request.getRemoteAddr());		person.setDateLastActived(new Date());		personService.save(person);		request.setAttribute("message", "歡迎回來");		return new ActionForward("success", "/jsp/person/success.jsp", false);	}	public ActionForward logout(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("用戶注銷");		request.getSession(true).setAttribute(PersonUtil.PERSON_INFO, null);		return new ActionForward("login", "/jsp/person/login.jsp", false);	}}登錄效果如下

6.7、PersonAction代碼——查看用戶資料

package action;public class PersonAction extends ForumAction {	private IPersonService<Person> personService;	//結合前面代碼	public ActionForward view(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {		PersonForm personForm = (PersonForm) form;		personForm.setTitle("查看用戶資料");		Person person = personService.find(Person.class, personForm.getPerson().getId());		request.setAttribute("person", person);		return new ActionForward("view", "/jsp/person/viewPerson.jsp", false);	}}運行效果:

7、版面類型模塊

7.1、ICategoryService接口

ICategoryService不需要特別的方法,因此沒有定義任何操作
package Service;public interface ICategoryService<T extends Category> extends IService<T> {}

7.2、CategoryServiceImpl實現

CategotyServiceImpl只需要實現ServiceImpl的create()即可。
package Service;public class CategoryServiceImpl<T extends Category> extends ServiceImpl<T> implements ICategoryService<T> {		@Override	public void create(T category) {		if (dao.createQuery(" from Category c where c.name = :name and c.deleted = false ").setParameter("name", category.getName()).list().size() > 0) 			throw new RuntimeException("類別 " + category.getName() + " 已經存在。");		dao.create(category);	}}

7.3、CategoryForm代碼

package form;public class CategoryForm extends ForumForm {	private Category category = new Category();	public Category getCategory() {		return category;	}	public void setCategory(Category category) {		this.category = category;	}	public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {		return null;	}	public void reset(ActionMapping mapping, HttpServletRequest request) {	}}

7.4、CategoryAction代碼——實現瀏覽類別

瀏覽類別時會顯示類別的版面、版面的帖子數、回帖數、最后發表的帖子等。
package action;public class CategoryAction extends ForumAction {	private ICategoryService<Category> categoryService;	public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		CategoryForm categoryForm = (CategoryForm) form;		List<Category> categoryList = categoryService.list(" from Category where deleted = false ", 0, Integer.MAX_VALUE,null);		request.setAttribute("categoryList", categoryList);		return new ActionForward("list", "/jsp/category/listCategory.jsp",false);	}	public ICategoryService<Category> getCategoryService() {		return categoryService;	}	public void setCategoryService(ICategoryService<Category> categoryService) {		this.categoryService = categoryService;	}}實現效果如圖:

7.5、CategoryAction代碼——實現添加類別

添加類別只是純粹地將類別保存進數據庫
package action;public class CategoryAction extends ForumAction {	private ICategoryService<Category> categoryService;	public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		CategoryForm categoryForm = (CategoryForm) form;		categoryForm.setTitle("添加類別");		return new ActionForward("add", "/jsp/category/addCategory.jsp", false);	}	public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		CategoryForm categoryForm = (CategoryForm) form;		categoryForm.setTitle("添加類別");		Category category = categoryForm.getCategory();		category.setDateCreated(new Date());		categoryService.create(category);		request.setAttribute("category", category);		return new ActionForward("add", "/jsp/category/success.jsp", false);	}}運行效果:

8、版面模塊

版面模塊包括添加版面、瀏覽版面帖子列表、設置版主等。

8.1、IBoradService接口

設置版主利用Hibernate的Cascade自動實現,因此不需要定義特別的操作。
package Service;public interface IBoardService<T extends Board> extends IService<T> {}

8.2、BoardServiceImpl實現

package Service;public class BoardServiceImpl<T extends Board> extends ServiceImpl<T> implements IBoardService<T> {	@Override	public void create(T board) {		if (dao.createQuery(" from Board b where b.deleted = false and b.name = :name ").setParameter("name", board.getName().trim()).list().size() > 0)			throw new RuntimeException("版面 " + board.getName() + " 已經存在。");		dao.create(board);	}}

8.3、BoardForm代碼

package form;public class BoardForm extends ForumForm {	private Category category = new Category();	private Board board = new Board();	private int[] adminId;	public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {		return null;	}	public void reset(ActionMapping mapping, HttpServletRequest request) {	}	//省略getter和setter方法}

8.4、BoardAction代碼——實現瀏覽版面

瀏覽版面會以分頁的形式列出所有的帖子,分頁使用Pagination類實現,放在uitl工具包里。
package action;public class BoardAction extends ForumAction {	private ICategoryService<Category> categoryService;	private IBoardService<Board> boardService;	private IThreadService<Thread> threadService;	private IPersonService<Person> personService;	@Override	@SuppressWarnings("all")	public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		BoardForm boardForm = (BoardForm) form;		Board board = boardService.find(Board.class, boardForm.getBoard().getId());		boardForm.setBoard(board);		int totalCount = threadService.getTotalCount(" select count(t) from Thread t "+ " where t.deleted = false and t.board.id = "+ board.getId(), null);		Pagination pagination = new Pagination(request, response);		pagination.setRecordCount(totalCount);		List<Thread> threadList = threadService.list(" select t from Thread t "+ " where t.deleted = false and t.board.id = " + board.getId()				+ " order by t.dateLastReplied desc ", pagination.getFirstResult(), pagination.getPageSize(), null);		request.setAttribute("board", board);		request.setAttribute("pagination", pagination);		request.setAttribute("threadList", threadList);		boardForm.setTitle("帖子列表 - 版面:" + board.getName());		return new ActionForward("list", "/jsp/thread/listThread.jsp", false);	}	//省略setter和getter方法}實現效果:

8.5、BoardAction代碼——實現版面添加

版面添加時需要選擇類別,因此需要將所有耳朵類別顯示出來。
package action;public class BoardAction extends ForumAction {	private ICategoryService<Category> categoryService;	private IBoardService<Board> boardService;	private IThreadService<Thread> threadService;	private IPersonService<Person> personService;	public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		BoardForm boardForm = (BoardForm) form;		boardForm.setTitle("添加版面");		List<Category> categoryList = categoryService.list(" from Category c where c.deleted = false ");		request.setAttribute("categoryList", categoryList);		return new ActionForward("add", "/jsp/board/addBoard.jsp", false);	}	public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		BoardForm boardForm = (BoardForm) form;		boardForm.setTitle("添加版面");		Category category = categoryService.find(Category.class, boardForm.getCategory().getId());		Board board = boardForm.getBoard();		board.setCategory(category);		board.setDateCreated(new Date());		boardService.create(board);		request.setAttribute("category", category);		return new ActionForward("success", "/jsp/board/success.jsp", false);	}}實現效果:

8.6、BoardAction代碼——設置版主

設置版主要顯示版面的信息、待選的版主列表,并且現在的版主要處于選中狀態。
package action;public class BoardAction extends ForumAction {	private ICategoryService<Category> categoryService;	private IBoardService<Board> boardService;	private IThreadService<Thread> threadService;	private IPersonService<Person> personService;	public ActionForward initSetAdmin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		BoardForm boardForm = (BoardForm) form;		Board board = boardService.find(Board.class, boardForm.getBoard().getId());		List<Person> personList = personService.list(" from Person p where p.deleted = false ");		int[] adminId = new int[board.getAdministrators().size()];		int i = 0;		for (Iterator<Person> it = board.getAdministrators().iterator(); it.hasNext(); i++) {			Person p = it.next();			adminId[i] = p.getId();		}		boardForm.setAdminId(adminId);		request.setAttribute("board", board);		request.setAttribute("personList", personList);		boardForm.setTitle("設置管理員 - 版面:" + board.getName());		return new ActionForward("success", "/jsp/board/setAdmin.jsp", false);	}	public ActionForward setAdmin(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		BoardForm boardForm = (BoardForm) form;		Board board = boardService.find(Board.class, boardForm.getBoard().getId());		board.getAdministrators().clear();		int[] adminId = boardForm.getAdminId();		for (int i = 0; adminId != null && i < adminId.length; i++) {			Person person = personService.find(Person.class, adminId[i]);			board.getAdministrators().add(person);		}		boardService.save(board);		boardForm.setTitle("設置管理員 - 版面:" + board.getName());		return new ActionForward("success", "/jsp/board/success.jsp", false);	}}實現效果:

9、帖子模塊

帖子模塊包括瀏覽帖子與發表帖子,瀏覽帖子會以分頁的形式列出所有回帖,發表帖子時允許編輯HTML代碼。

9.1、IThreadService接口

瀏覽帖子時需要統計帖子的點擊率
package Service;public interface IThreadService<T extends Thread> extends IService<T> {	public void updateHit(Integer threadId);}

9.2、ThreadServiceImpl實現

發表帖子時需要更新版面的信息,包括帖子數、最后發表的帖子、作者、時間等
package Service;public class ThreadServiceImpl<T extends Thread> extends ServiceImpl<T> implements IThreadService<T> {	@Override	@SuppressWarnings("all")	public void create(T thread) {		dao.create(thread);		int totalCount = dao.getTotalCount(" select count(t) from Thread t "+ " where t.deleted = false and t.board.id = "+ thread.getBoard().getId(), null);		dao.createQuery(" update Board b "+ " set b.lastThread.id = :lastThreadId, b.lastReply.id = null, threadCount = :threadCount "+ " where b.id = :boardId ").setParameter(						"lastThreadId", thread.getId()).setParameter("boardId",thread.getBoard().getId()).setParameter("threadCount",totalCount).executeUpdate();	}	public void updateHit(Integer threadId) {		dao.createQuery(" update Thread t set t.hit = t.hit + 1 where t.id = :id ").setParameter("id", threadId).executeUpdate();	}}

9.3、ThreadForm代碼

package form;public class ThreadForm extends ForumForm {	private Thread thread = new Thread();	private Board board = new Board();	public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {		return null;	}	public void reset(ActionMapping mapping, HttpServletRequest request) {	}	//省略setter和getter方法}

9.4、ThreadAction代碼——實現瀏覽帖子

瀏覽帖子時以分頁的形式顯示所有的回帖,并更新人氣
package action;public class ThreadAction extends ForumAction {	private IThreadService<Thread> threadService;	private IPersonService<Person> personService;	private IBoardService<Board> boardService;	private IReplyService<Reply> replyService;	@Override	@SuppressWarnings("all")	public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		return this.view(mapping, form, request, response);	}	@SuppressWarnings("all")	public ActionForward view(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		ThreadForm threadForm = (ThreadForm) form;		Thread thread = threadService.find(Thread.class, (int) threadForm.getThread().getId());		int totalCount = replyService.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false and r.thread.id = "						+ threadForm.getThread().getId(), null);		Pagination pagination = new Pagination(request, response);		pagination.setRecordCount(totalCount);		List<Reply> replyList = replyService.list(" from Reply r where r.deleted = false and r.thread.id = "+ threadForm.getThread().getId()						+ " order by r.id asc ", pagination.getFirstResult(),pagination.getPageSize(), null);		threadService.updateHit(thread.getId());		request.setAttribute("category", thread.getBoard().getCategory());		request.setAttribute("board", thread.getBoard());		request.setAttribute("thread", thread);		request.setAttribute("pagination", pagination);		request.setAttribute("replyList", replyList);		threadForm.setTitle("瀏覽帖子 - 標題:" + thread.getTitle());		return new ActionForward("list", "/jsp/thread/viewThread.jsp", false);	}	//省略setter和getter方法}實現效果:

9.5、ThreadAction代碼——實現發表帖子

發表帖子時需要用到HTML編輯器,本系統采用tinyMCE,tinyMCE是js實現的編輯器,功能十分強大,而且使用十分簡單,只需要在JSP中引入即可。本系統把textArea變成HTML編輯器。
package action;public class ThreadAction extends ForumAction {	private IThreadService<Thread> threadService;	private IPersonService<Person> personService;	private IBoardService<Board> boardService;	private IReplyService<Reply> replyService;	public ActionForward initAdd(ActionMapping mapping, ActionForm form,			HttpServletRequest request, HttpServletResponse response) {		ThreadForm threadForm = (ThreadForm) form;		Board board = boardService.find(Board.class, threadForm.getBoard().getId());		threadForm.setBoard(board);		request.setAttribute("board", board);		threadForm.setTitle("發表帖子 - 版面:" + board.getName());		return new ActionForward("add", "/jsp/thread/addThread.jsp", false);	}	public ActionForward add(ActionMapping mapping, ActionForm form,			HttpServletRequest request, HttpServletResponse response) {		ThreadForm threadForm = (ThreadForm) form;		Board board = boardService.find(Board.class, threadForm.getBoard().getId());		PersonInfo personInfo = PersonUtil.getPersonInfo(request, response);		Person person = personService.find(Person.class, personInfo.getId());		Thread thread = threadForm.getThread();		thread.setBoard(board);		thread.setAuthor(person);		thread.setAuthorLastReplied(null);		thread.setDateCreated(new Date());		thread.setDateLastReplied(new Date());		thread.setDeleted(false);		thread.setIpCreated(request.getRemoteAddr());		thread.setReadonly(false);		thread.setReplyCount(0);		thread.setTopped(false);		threadService.create(thread);		threadForm.setTitle("發表帖子 - 版面:" + board.getName());		return this.list(mapping, form, request, response);	}}運行效果:

10、回帖模塊

回帖模塊只有回帖一個功能。

10.1、IReplyService接口

package Service;public interface IReplyService<T extends Reply> extends IService<T> {}

10.2、ReplyServiceImpl實現

發表回帖時,需要更新版面最后發表的回帖、作者、時間,并更新帖子最后回復的回帖、作者、時間,以及回帖總數。
package Service;public class ReplyServiceImpl<T extends Reply> extends ServiceImpl<T> implements IReplyService<T> {	@Override	public void create(T reply) {		dao.create(reply);		// 更新帖子最后回復、最后回復日期、作者、回帖數		int count = dao.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false and r.thread.id = "+ reply.getThread().getId(), null);		dao.createQuery(" update Thread t "+ " set t.authorLastReplied.id = :authorLastReplied, "+ " t.dateLastReplied = :dateLastReplied, "				+ " t.replyCount = :replyCount "+ " where t.id = :threadId ").setParameter("authorLastReplied", reply.getAuthor().getId()).setParameter(				"dateLastReplied", reply.getDateCreated()).setParameter("replyCount", count).setParameter("threadId",reply.getThread().getId()).executeUpdate();		// 更新版面的最后發表數、最后發表時間		int replyCount = dao.getTotalCount(" select count(r) from Reply r "+ " where r.deleted = false " + " and r.thread.board.id = "+ reply.getThread().getBoard().getId(), null);		dao.createQuery(" update Board b " + " set b.lastThread.id = null, "+ " b.lastReply.id = :lastReplyId, "				+ " b.replyCount = :replyCount "+ " where b.id = :boardId ").setParameter(				"lastReplyId", reply.getId()).setParameter("boardId",reply.getThread().getBoard().getId()).setParameter("replyCount", replyCount).executeUpdate();		int floor = dao.getTotalCount(" select count(r) from Reply r "+ " where r.thread.id = " + reply.getThread().getId(), null);		// 回帖處于第幾樓		reply.setFloor(floor);		dao.save(reply);	}}

10.3、ReplyForm代碼

package form;public class ReplyForm extends ForumForm {	private Thread thread = new Thread();	private Reply reply = new Reply();	public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {		return null;	}	public void reset(ActionMapping mapping, HttpServletRequest request) {	}	//省略setter和getter方法}

10.4、ReplyAction代碼——實現發表回帖

package action;public class ReplyAction extends ForumAction {	private IPersonService<Person> personService;	private IThreadService<Thread> threadService;	private IReplyService<Reply> replyService;	public ActionForward list(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		ReplyForm replyForm = (ReplyForm) form;		return null;	}	public ActionForward initAdd(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		ReplyForm replyForm = (ReplyForm) form;		Thread thread = threadService.find(Thread.class, (int) replyForm.getThread().getId());		request.setAttribute("category", thread.getBoard().getCategory());		request.setAttribute("board", thread.getBoard());		request.setAttribute("thread", thread);		replyForm.setTitle("回復帖子 - 標題:" + thread.getTitle());		return new ActionForward("add", "/jsp/reply/addReply.jsp", false);	}	public ActionForward add(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {		ReplyForm replyForm = (ReplyForm) form;		Thread thread = threadService.find(Thread.class, (int) replyForm.getThread().getId());		PersonInfo personInfo = PersonUtil.getPersonInfo(request, response);		Person person = personService.find(Person.class, personInfo.getId());		Reply reply = replyForm.getReply();		reply.setThread(thread);		reply.setDateCreated(new Date());		reply.setDeleted(false);		reply.setAuthor(person);		replyService.create(reply);		request.setAttribute("category", thread.getBoard().getCategory());		request.setAttribute("board", thread.getBoard());		request.setAttribute("thread", thread);		request.setAttribute("reply", reply);		replyForm.setTitle("回復帖子 - 標題:" + thread.getTitle());		return new ActionForward("success", "/jsp/reply/success.jsp", false);	}	//省略setter和getter方法}實現效果:
上一篇:搜索剪枝

下一篇:Dirt HDU - 3023 題解

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 贞丰县| 项城市| 太仆寺旗| 阿鲁科尔沁旗| 莫力| 资溪县| 慈利县| 河北区| 晋中市| 昔阳县| 临安市| 大厂| 阿合奇县| 历史| 汶上县| 沛县| 连云港市| 镇原县| 客服| 江北区| 剑川县| 南康市| 平阳县| 通许县| 兴宁市| 镇巴县| 延川县| 华亭县| 阿拉尔市| 冀州市| 伊宁市| 乐都县| 和平县| 富阳市| 曲松县| 巨野县| 宜州市| 万盛区| 西华县| 商丘市| 台山市|