内容管理项目小结 成功案例-公司官网,游戏官网
1,架构
2,技术架构
3,应用的启动过程
4,用户的访问过程(前端为静态的html页面,这里主要是后端)
5,高级的地方,通过泛型,抽象了整个的MVC访问过程,对增删改查只写了一份代码,每一个新增的业务只需增加几个类,继承复用泛型类即可。
<!-- 创建游戏产品 -->
<action name="add" class="com.sz7road.web.action.admin.gameproduct.GameProductAction" method="modify">
<param name="operation">add</param>
<result name="input" type="tiles">adminGameProductAdd</result>
<result name="success" type="redirectAction">list</result>
<interceptor-ref name="globalInterceptorStack"></interceptor-ref>
</action>
<!-- 编辑游戏产品 -->
<action name="edit" class="com.sz7road.web.action.admin.gameproduct.GameProductAction" method="modify">
<param name="operation">edit</param>
<result name="success" type="redirectAction">list</result>
<result name="input" type="tiles">adminGameProductEdit</result>
<interceptor-ref name="globalInterceptorStack"></interceptor-ref>
</action>
<!-- 删除游戏产品 -->
<action name="del" class="com.sz7road.web.action.admin.gameproduct.GameProductAction" method="modify">
<param name="operation">del</param>
<result name="input" type="redirectAction">list</result>
<result name="success" type="redirectAction">list</result>
<interceptor-ref name="globalInterceptorStack"></interceptor-ref>
</action>
<!-- 查询游戏产品 -->
<action name="list" class="com.sz7road.web.action.admin.gameproduct.GameProductAction" method="list">
<param name="operation">list</param>
<result name="input" type="tiles">adminHomePage</result>
<result name="success" type="tiles">adminGameProductList</result>
<interceptor-ref name="globalInterceptorStack"></interceptor-ref>
</action>
public String modify() throws Exception {
EditType editType = EditType.getEnumType(getOperation());
if (null == editType) {
addActionError("operation参数非法");
return ActionSupport.INPUT;
}
boolean result = false;
try {
result = getService().modifyItem(editType, getT(), getDeleteIdArray());
} catch (Exception e) {
e.printStackTrace();
return ActionSupport.ERROR;
}
if (result) {
msg = getText("operation.success");
return ActionSupport.SUCCESS;
} else {
return ActionSupport.ERROR;
}
}
public String list() throws Exception {
paginationResult = new PaginationResult<T>();
dataList = getService().searchByPage(getPager());
final int total = getService().getTotalCount();
paginationResult.setTotal(total);
paginationResult.setResultList(dataList);
requestMap.put(AppConstant.PAGE_MAP_OBJECT, paginationResult);
return ActionSupport.SUCCESS;
}
@Override
public List<T> listByPage(Pager pager) {
boolean result = false;
final Session session = getCurrentSession();
Transaction transaction = session.beginTransaction();
List<T> list = null;
try {
final int pageSize = pager.getPageSize();
final int startPage = (pager.getPageIndex() - 1) * pageSize;
final StringBuffer queryStringBuffer = new StringBuffer(" from " + domainObjectName + " as " + instanceName );
if(!Strings.isNullOrEmpty(pager.getSearchField()))
{
queryStringBuffer.append(" where "+instanceName + "." + pager.getSearchField() + " ").append(pager.getSearchOperation()+ " '").append(pager.getSearchValue()+"'");
}
queryStringBuffer.append(" order by ").append(instanceName + "." + pager.getSortField() + " " + pager.getSortOrder());
// queryStringBuffer.append(" limit ").append(startPage).append(" , " + pageSize);
Query query = session.createQuery(queryStringBuffer.toString());
query.setFirstResult(startPage);
query.setMaxResults(pageSize);
list = query.list();
transaction.commit();
} catch (Exception ex) {
ex.printStackTrace();
transaction.rollback();
} finally {
return list;
}
}
public boolean update(final T entity) {
boolean result = false;
final Session session = getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
if(entity.getId()>0){
session.update(entity);
result=true;
} else{
result = session.save(entity) != null;
}
transaction.commit();
} catch (Exception ex) {
ex.printStackTrace();
transaction.rollback();
} finally {
return result;
}
}
6,tiles和基本展示控件包的使用
指定好定义tiles的配置文件,对象工厂,以及监听器即可
<context-param>
<param-name>org.apache.tiles.CONTAINER_FACTORY</param-name>
<param-value>org.apache.struts2.tiles.StrutsTilesContainerFactory</param-value>
</context-param>
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name><param-value>
/WEB-INF/tiles/tiles.xml,
/WEB-INF/tiles/tiles-adminlogin.xml,
/WEB-INF/tiles/tiles-adminPermission.xml,
/WEB-INF/tiles/tiles-adminUser.xml,
/WEB-INF/tiles/tiles-adminEvent.xml,
/WEB-INF/tiles/tiles-adminAgent.xml,
/WEB-INF/tiles/tiles-adminRecruit.xml,
/WEB-INF/tiles/tiles-adminCompanyInfo.xml,
/WEB-INF/tiles/tiles-adminCategory.xml,
/WEB-INF/tiles/tiles-adminAt7road.xml,
/WEB-INF/tiles/tiles-adminGameProduct.xml,
/WEB-INF/tiles/tiles-adminCarousel.xml
</param-value>
</context-param>
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<!--首页-->
<definition name="adminDefaultLayout" template="/WEB-INF/web/common/admin/admin_layout.jsp">
<put-attribute name="titleKey" value="PageTitle" type="string"/>
<put-attribute name="header" value="/WEB-INF/web/common/admin/admin_header.jsp"/>
<put-attribute name="leftbar" value="/WEB-INF/web/common/admin/admin_left.jsp"/>
<put-attribute name="content" value=""/>
<put-attribute name="footer" value="/WEB-INF/web/common/admin/admin_footer.jsp"/>
</definition>
</tiles-definitions>模版定制
<tiles-definitions>
<definition name="adminCategoryAdd" extends="adminDefaultLayout">
<put-attribute name="titleKey" value="admin.categoryManage.add"/>
<put-attribute name="content" value="/WEB-INF/web/admin/category/admin_createCategory.jsp" />
</definition>个性实例
主要看展示数据的控件的使用:
<pg:pager items="<%=paginationResult.getTotal()%>"
url='<%=request.getContextPath()+"/gameProduct/list.action"%>'
index="center"
maxPageItems='<%= Integer.parseInt(SystemConfig.getProperty("admin.search.page.size")) %>'
maxIndexPages='<%= Integer.parseInt(SystemConfig.getProperty("admin.search.max.index.pages")) %>'
isOffset="true" export="offset,currentPageNumber=pageNumber" scope="request">
<display:table name="requestScope.paginationResult.resultList" class="tablelist"
defaultsort="0" cellpadding="0" cellspacing="0" style="width:99%"
requestURI="" id="gameProduct">
<%--<display:column property="id" titleKey="admin.id" style="width:30px;"/>--%>
<display:column property="orderNum" titleKey="admin.orderNum"/> //序号
<display:column property="gameName" maxLength="5" titleKey="admin.gameProduct.gameName"/> //游戏名称
<display:column property="gameTitle" maxLength="5" titleKey="admin.gameProduct.gameTitle"/> //游戏标题
<display:column property="gameWebsiteUrl" maxLength="15" titleKey="admin.gameProduct.gameWebsiteUrl"/>//官网地址
<display:column property="gamePlayUrl" maxLength="15" titleKey="admin.gameProduct.gamePlayUrl"/>//选服页地址
<display:column property="gameHtmlName" maxLength="5" titleKey="admin.gameProduct.gameHtmlName"/>//html名称
<display:column property="gameImgShowInProduct" maxLength="20" titleKey="admin.gameProduct.gameImgShowInProduct"/>//产品图片
<display:column property="gameShortDesc" maxLength="5" titleKey="admin.gameProduct.gameShortDesc" escapeXml="true"/>//简介
<display:column property="gameDetailDesc" maxLength="5" titleKey="admin.gameProduct.gameDetailDesc" escapeXml="true"/>//详细
<display:column property="createTime" style="width:50px;" titleKey="admin.createTime" format="{0,date,yyyy-MM-dd}"/>//创建日期
<display:column style="width:60px;" titleKey="admin.common.operation" href='${path}/gameProduct/edit.action'>
<s:url id="editUrl" namespace="/gameProduct" action="editPage">
<s:param name="gameProduct.id"><s:property value="#attr.gameProduct.id"/></s:param>
</s:url>
<s:a href="%{editUrl}"><s:text name="admin.common.edit"/></s:a>
<a href="#" onClick="deleteGameProduct('<s:property value="#attr.gameProduct.id"/>','<s:property value="#attr.gameProduct.gameName"/>')"><s:text name="admin.common.delete"/></a>
</display:column>
</display:table>
<jsp:include page="/WEB-INF/web/common/pagination2.jsp" flush="true" />
</pg:pager>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page session="false" %>
<%@ taglib uri="/WEB-INF/pager-taglib.tld" prefix="pg" %>
<jsp:useBean id="currentPageNumber" type="java.lang.Integer" scope="request"/>
<jsp:useBean id="totalItems" type="java.lang.Integer" scope="request"/>
<jsp:useBean id="maxPageItems" type="java.lang.Integer" scope="request"/>
<br>
<span class="tabletitle">Result Page: </span>
<span class="content">
<%
int totalItemCount = totalItems.intValue();
int pageSise = maxPageItems.intValue();
if(totalItemCount < 1){
%>
没有查询到任何记录.
<%
}else if(totalItemCount == 1){
%>
1 - <%= totalItemCount %> of <%= totalItemCount %> record.
<%
}else if(totalItemCount <= pageSise){
%>
1 - <%= totalItemCount %> of <%= totalItemCount %> records.
<%
}
%>
<pg:index export="total=itemCount">
<pg:page export="first,last">
<%= first %> - <%= last %> of <%= total %> records.
</pg:page>
<pg:first export="firstPageUrl=pageUrl" unless="current">
<a href="<%= firstPageUrl %>">第一页</a>
</pg:first>
<pg:prev export="prevPageUrl=pageUrl">
<a href="<%= prevPageUrl %>">前一页</a>
</pg:prev>
<pg:pages><%
if (pageNumber == currentPageNumber) {
%> <b><%= pageNumber %></b> <%
} else {
%> <a href="<%= pageUrl %>"><%= pageNumber %></a> <%
}
%></pg:pages>
<pg:next export="nextPageUrl=pageUrl">
<a href="<%= nextPageUrl %>">后一页</a>
</pg:next>
<pg:last export="lastPageUrl=pageUrl" unless="current">
<a href="<%= lastPageUrl %>">末页</a>
</pg:last>
</pg:index>
</span>
<br>
7,小结
这是一个简单却经典的内容管理系统,在后台管理数据,对数据进行增删改查,数据管理好之后,使用freemarker生成静态的html页面,同时静态资源分域,加快了站点的显示速度;
后台使用泛型和抽象类,大大的减少了重复代码的数量,引入Guice容器,减少了对象的实例的互相依赖,同时使得程序的结构更加的清晰,hibernate简化了持久层代码的编写,tiles和数据展示控件的使用使得后端的数据展示比较美观,简单却使用的站点发布系统,通过这个项目,我熟悉了struts2,guice,hibernate,tiles技术,唯一一个觉得比较不妥的地方就是虽然大大的减少了重复代码,但是新增模块的话需要增加很多的类,如果可以定义一个公共的动态定位的类来顶替这些大量的只是简单继承的类我觉得后端的代码会更加整洁。