1、樹狀菜單加載javascript
這是js的一個典型應用,使用zTree插件可以完成該項任務http://www.ztree.me/v3/main.phpphp
我是用的版本:zTree2.5css
使用方法:html
1 <%@ page language="java" isELIgnored="false" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <meta http-equiv="content-type" content="text/html;charset=utf-8"> 7 <title>導航菜單</title> 8 <link rel="stylesheet" href="${pageContext.servletContext.contextPath}/css/menu.css" type="text/css"> 9 <link rel="stylesheet" href="${pageContext.servletContext.contextPath}/css/ztree/zTreeStyle/zTreeStyle.css" type="text/css"> 10 <%@ include file="/jsp/common.jsp" %> 11 <script type="text/javascript" src="${pageContext.servletContext.contextPath}/js/ztree/jquery-ztree-2.5.js"></script> 12 <script type="text/javascript" src="${pageContext.servletContext.contextPath}/js/menu_tree.js"></script> 13 </head> 14 15 <body> 16 <TABLE border=0 height=600px align=left> 17 <TR> 18 <TD width=230px align=left valign=top style="BORDER-RIGHT: #999999 1px dashed"> 19 <ul id="tree" class="tree" style="width:230px; overflow:auto;"></ul> 20 </TD> 21 </TR> 22 </TABLE> 23 </body> 24 </html>
核心代碼:前端
<TABLE border=0 height=600px align=left> <TR> <TD width=230px align=left valign=top style="BORDER-RIGHT: #999999 1px dashed"> <ul id="tree" class="tree" style="width:230px; overflow:auto;"></ul> </TD> </TR> </TABLE>
最重要的就是ul標籤了,該標籤的id屬性值爲tree,是加載樹形插件的關鍵。java
樹形菜單的加載方式分爲兩種,一種是一次性加載,另一種就是單擊觸發式的加載。一次性加載的方法比較簡單,可是面對大數據菜單的時候響應速度慢,用戶體驗很很差,因此這裏使用了單擊觸發式的加載。node
var tree={ zTree:'',//經過調用post方法返回的對象 pNode:'',//父節點 setting:{ isSimpleData: true, treeNodeKey: "mid", treeNodeParentKey: "pid", showLine: true, root:{ isRoot:true, nodes:[] }, callback:{ expand:function(event, treeId, treeNode){ tree.pNode=treeNode;//共享以後就不須要傳遞參數了。 treeNode.isParent=true, tree.loadNodeByPNode(); } } }, //加載樹根的方法 loadRoot:function(){ var parameters={ //首先加載父節點爲0的樹,即第一級目錄 pid:0 }; $.post("Menuitem_showMenuItemsByPid.action",parameters,function(data){ tree.zTree=$("#tree").zTree(tree.setting,data.menuitems); var node=tree.zTree.getNodeByParam("mid","1"); tree.pNode=node; tree.loadNodeByPNode(); tree.zTree.expandNode(node,true); }); }, loadNodeByPNode:function(){ var parameters={ //首先加載父節點爲0的樹,即第一級目錄 pid:tree.pNode.mid }; //這裏須要先進行判斷當前節點是否有子節點 if(!tree.zTree.getNodeByParam('pid',tree.pNode.mid)){ $.post("Menuitem_showMenuItemsByPid.action",parameters,function(data){ // $("#tree").zTree(tree.setting,data.menuItems); tree.zTree.addNodes(tree.pNode,data.menuitems,true); if(tree.pNode.mid==1){ var node=tree.zTree.getNodeByParam("mid","11"); tree.pNode=node; tree.loadNodeByPNode(); tree.zTree.expandNode(node,true); } }); } } }; $().ready(function(){ tree.loadRoot(); });
採用面面向對象的方法編程層次結構更加清晰,這裏涉及到了向數據庫發起異步請求的ajax方法以及在異步請求的狀況下默認展開菜單的處理方法。jquery
2、定時器的設計方法git
普通的定時器實現方法有好多種,一開始我使用了監聽器和Servlet的方法,可是實現起來都不是那麼駕輕就熟,由於須要考慮到諸如目標對象建立時間問題等等麻煩問題,最好的方式是肯定目標對象必定建立完成以後再調用相關的方法。如今目標對象是RoomServiceImpl,個人需求是須要該對象歸入Spring容器管理以後調用該類中的一個初始化定時器的一個方法。很明顯,最好的實現方法是使用@PostConstruct註解,該註解的做用就是當對象在Spring中建立以後自動調用一個方法。該方法的調用時間在構造方法以後。github
@PostConstruct public void init() { //設置一個定時器,天天00:00的時候對房間狀態進行更新 System.out.println("天天00:00進行定時更新"); Calendar calendar=Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY,24); calendar.set(Calendar.MINUTE,0); calendar.set(Calendar.SECOND, 1); Timer timer=new Timer(); timer.schedule(new TimerTask(){ @Override public void run() { //天天00:00準時刷新數據 refreshRoomState(); } }, calendar.getTime(),24*60*60*1000); }
refreshRoomState方法是最終將要定時執行的方法,該方法將使用到該對象中的某些對象屬性。因此初始化對象的同時必須還要將屬性值設置好,這就是spring容器的問題了。
最關鍵的就是該方法調用的時機和定時器的使用方法。
3、日期插件的使用。
日期插件不少,可是像樣的卻沒有幾個。這裏使用了老牌的日期插件DatePicker http://www.my97.net/dp/down.asp
個人項目中的使用版本是最新的版本:https://github.com/kdyzm/HotelMembersManagement/tree/master/WebRoot/js/datePicker
使用該日期插件的好處就是可以很方便的顯示時分秒
1.顯示時分秒的使用方法:
<input type="text" id="d241" onfocus="WdatePicker({dateFmt:'yyyy年MM月dd日 HH時mm分ss秒'})" class="Wdate" style="width:300px"/>
2.只是有年月日的使用方法,這種方法是最常規的使用方式
<input id="d11" type="text" onClick="WdatePicker()"/>
4、DAO層和Action層代碼重用
1.首先DAO的頂層接口:BaseDao
import java.io.Serializable; import java.util.Collection; public interface BaseDao<T>{ public Collection<T> getAllEntry(); public T getEntryById(Serializable id); public void saveEntry(T t); public void deleteEntry(T t); public void updateEntry(T t); }
實現該接口的頂層父類:BaseDaoImpl,全部的DAO實現類都要繼承該父類
import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.Collection; import javax.annotation.Resource; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.transaction.annotation.Transactional; import com.kdyzm.dao.base.BaseDao; public class BaseDaoImpl<T> implements BaseDao<T>{ //泛型的真實類型 private Class<T> clazz; @Resource(name="hibernateTemplate") public HibernateTemplate hibernateTemplate; public BaseDaoImpl() { //在默認構造方法中獲得真實的類型 //ParameterizedType就是泛型 ParameterizedType pt=(ParameterizedType) this.getClass().getGenericSuperclass(); this.clazz=(Class) pt.getActualTypeArguments()[0];//獲得實際的參數類型,<T> // System.out.println(clazz.getSimpleName()); // System.out.println(pt.getRawType());//打印聲明該方法的類或者接口類型,BaseServiceImpl } public HibernateTemplate getHibernateTemplate() { return hibernateTemplate; } public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } @Override public Collection<T> getAllEntry() { Collection<T> collection= this.hibernateTemplate.find("from "+clazz.getName()); return collection; } @Override public T getEntryById(Serializable id) { return (T) this.hibernateTemplate.get(clazz, id); } @Override @Transactional(readOnly=false) public void saveEntry(T t) { this.hibernateTemplate.save(t); } @Override @Transactional(readOnly=false) public void deleteEntry(T t) { this.hibernateTemplate.delete(t); } @Transactional(readOnly=false) @Override public void updateEntry(T t) { this.hibernateTemplate.update(t); } }
其中最重要的就是在構造方法中的語句
public BaseDaoImpl() { //在默認構造方法中獲得真實的類型 //ParameterizedType就是泛型 ParameterizedType pt=(ParameterizedType) this.getClass().getGenericSuperclass(); this.clazz=(Class) pt.getActualTypeArguments()[0];//獲得實際的參數類型,<T> // System.out.println(clazz.getSimpleName()); // System.out.println(pt.getRawType());//打印聲明該方法的類或者接口類型,BaseServiceImpl }
兩句代碼是最重要的核心代碼。
2.Action同理
import java.lang.reflect.ParameterizedType; import org.apache.struts2.json.annotations.JSON; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{ private static final long serialVersionUID = -1344990340960028510L; private T t; private Class<T> clazz; //使用構造方法建立T對象 public BaseAction(){ ParameterizedType parameterizedType=(ParameterizedType) this.getClass().getGenericSuperclass(); this.clazz=(Class<T>) parameterizedType.getActualTypeArguments()[0]; System.out.println(parameterizedType.getRawType()); try { this.t=(T) this.clazz.newInstance(); } catch(Exception e){ e.printStackTrace(); } } public static final String LIST_ACTION="listAction"; public static final String ADDUI="addUI"; public static final String UPDATEUI="updateUI"; public static final String ACTIONTOACTION="actionToAction"; public static final String AJAXRESPONSE="ajaxResponse"; public String listAction=LIST_ACTION; public String addUI=ADDUI; public String updateUI=UPDATEUI; public String actionToAction=ACTIONTOACTION; public String ajaxResponse=AJAXRESPONSE; @Override @JSON(serialize=false) public T getModel() { return t; } }
5、實數的精度控制問題
使用DecimalFormat類可以很方便的實現精度控制,以精確到小數點後兩位爲例:
public class DecimalUtils { public static String pattern="#.00"; public static String get(double source){ DecimalFormat df=new DecimalFormat(pattern); return df.format(source); } }
6、日期處理問題
寫了一個日期處理的工具類實現很方便的日期處理
package com.kdyzm.utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 日期處理工具類 * @author kdyzm * */ public class DateUtils { //默認的日期格式 private static String pattern="yyyy-MM-dd HH:mm:ss"; public static void resetDefault(){ pattern="yyyy-MM-dd HH:mm:ss"; } public static void setPattern(String p){ pattern=p; } public static String getPattern(){ return pattern; } //日期格式對象轉換成字符串 public static String dateToString(Date date){ SimpleDateFormat sdf=new SimpleDateFormat(pattern); String dateString=sdf.format(date); return dateString; } //字符串格式轉化成日期對象 public static Date stringToDate(String dateString){ SimpleDateFormat sdf=new SimpleDateFormat(pattern); Date date=null; try { date=sdf.parse(dateString); } catch (ParseException e) { e.printStackTrace(); } return date; } //獲取年月日的方法,日期格式是yyyy-MM-dd HH:mm:ss public static String getYMDByDateString(String dateString){ return dateString.split(" ")[0]; } //獲取小時的方法,日期格式是yyyy-MM-dd HH:mm:ss public static String getHHByDateString(String dateString){ return dateString.split(" ")[1].split(":")[0]; } //測試工具類 public static void main(String[] args) { DateUtils.setPattern("yyyy年MM月dd日 HH時mm分ss秒"); String dateString="2015年10月8日 13時15分28秒"; Date date =new Date(); System.out.println(DateUtils.stringToDate(dateString)); System.out.println(DateUtils.dateToString(date)); } }
7、使用struts2jar包實現前端和struts2交互的問題
使用的jar包版本頗有問題,版本不正確各類問題都會出現。這裏使用的版本是2.1.8
必須加入三個jar包:https://github.com/kdyzm/HotelMembersManagement/tree/master/WebRoot/WEB-INF/lib/json
使用方法就是在Action中加入一個String類型的字段,並提供get和set方法
private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; }
在前端獲取該響應信息:
$.post("Json_CardAction_isCardExists.action",parameter,function(data){ if(data.message=="1"){ }else{
}
Action中全部不須要返回到前端的數據的get方法以前必定要加上@JSON(serialize=false)註解。
方法名稱儘可能不要使用getXXX,而要使用showXXX方法代替。
特別是接口類型的引用更應該如此。不然的話必定會報錯。
8、fckEditor插件的使用問題
借用demo便可。