林炳文Evankaka原創做品。css
轉載請註明出處http://blog.csdn.net/evankaka
html
摘要:在程序開發過程當中。一些IDE的配置、常用代類的積累以及常用框架的使用。java
能幫助咱們迅速寫好代碼,高速定位錯誤。同一時候,又有利於咱們高速構造和部署,以及進行興許的迭代開發。mysql
文件夾:linux
1、IDE配置篇git
2、規範project篇web
3、常用代碼篇spring
4、常用框架篇sql
5、其它工具
數據庫
平時開發因爲是選用Eclipse,因此在配置上假設一開始就配置好的話,開發的過程當中就可以省去很是多步驟。首先是IDE的選擇,這裏因爲平時用得最多的是Eclipse,因此主要仍是針對它來講。到官網上去下載IDE,假設不作JAVA EE開發,建議選擇第二個,固然。假設作安卓開發,也可以直接去下一直帶有安卓SDK的Eclipse.
Eclipse代碼裏面的代碼提示功能默認是關閉的。僅僅有輸入「.」的時候纔會提示功能,如下說一下怎樣改動eclipse配置,開啓代碼本身主動提示功能 Eclipse -> Window -> Perferences->Java -> Editor -> Content Assist 如下有三個選項,找到第二個「Auto activation triggers for Java:」選項 在其後的文本框中會看到一個「.」存在。這表示:僅僅有輸入「.」以後纔會有代碼提示和本身主動補全,咱們要改動的地方就是這裏。把該文本框中的「.」換掉。換成「abcdefghijklmnopqrstuvwxyz.」。這樣。你在Eclipse裏面寫Java代碼就可以作到按「abcdefghijklmnopqrstuvwxyz.」中的隨意一個字符都會有代碼提示。
這是下個本身主動提示的樣例
在ssh或ssm框架中,都要寫很是多的XML配置代碼。
假設能在寫的時候。本身主動顯示一些提示代碼。那就可以很是高速的把代碼寫出來。
DTD 類型約束文件
1. Window->Preferences->XML->XML Catalog->User Specified Entries窗體中,選擇Add 按紐
2.在Add XML Catalog Entry 對話框中選擇或輸入如下內容:
Location: F:/soft/programmingSoft/Framework/Ibatis/sql-map-config-2.dtd
Key Type: URI
KEY: http://ibatis.apache.org/dtd/sql-map-config-2.dtd
XSD 類型約束文件
1. Window->Preferences->XML->XML Catalog->User Specified Entries窗體中,選擇Add 按紐
2.在Add XML Catalog Entry 對話框中選擇或輸入如下內容:
Location: F:/soft/programmingSoft/Framework/Spring/spring-framework-2.5.6.SEC01-with-dependencies/spring-framework-2.5.6.SEC01/dist/resources/spring-beans-2.5.xsd
Key Type: Schema Location
KEY: http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
一、Java代碼本身主動凝視
在使用Eclipse 編寫Java代碼時,本身主動生成的凝視信息都是依照預先設置好的格式生成的。
打開Windows->Preferences->Java->Code Style->Code Templates,點擊右邊窗體中的Comments,可以看到有很是多選項。咱們即可對此凝視信息模板進行編輯。
如咱們但願在一個Java文件的開頭設置做者信息、日期信息。
爲類和方法作凝視標準
注:方法的凝視本身主動生成方式爲:輸入/** 而後按下enter就能夠。
或者在你需要加入凝視的地方點擊Sources->Ganarate Element Comment,或者使用快捷鍵 Alt+Shift+J ,則 eclipse 本身主動在該類前面加入凝視。
二、jsp 文件部分
eclipse-->windows-->preferences-->Web-->JSP Files-->Editer-->Templates-->New JSP File-->單擊[edit]button
在文件首行,加入例如如下內容:
Java代碼
<%--
建立時間:${date}${time}
創 建 人:daniel
相關說明:
JDK1.6.0_21 tomcat6.0.29 servlet2.5
--%>
<%--
建立時間:${date}${time}
創 建 人:daniel
相關說明:
JDK1.6.0_21 tomcat6.0.29 servlet2.5
--%>
這樣再建立 .java 或 .jsp 文件時,eclipse 就會爲咱們本身主動將凝視寫好。
你還可以經過「導出」、「導入」功能,把本身的模板導出來,方便在其它機器上使用。
在開發過程當中。是否是感到白色的一片看得很是不舒服,特別是晚上的時候,屏幕太亮了。對眼晴實在很差。所幸Eclipse有這方面的皮膚庫。在Eclipse lua中有自帶的一個皮膚庫Dark,選擇方法
Window—>Preferences—>General—>Apperance選擇主題爲Dark。確認
結果例如如下
不少其它的皮膚模板請到這裏來下吧!
快捷操做平時是我使用最多的,用鍵盤的速度確定比用鼠標來得快。高手都是直接快捷鍵來定位各類問題。
如下是一些我本身比較常用的快捷鍵,有興趣的人也可以本身去百度下。
一、Ctrl+Shift+t:打開類型
假設你不是有意磨洋工,仍是忘記經過源代碼樹(source tree)打開的方式吧。用eclipse很是easy打開接口的實現類
二、Alt+左右方向鍵:返回與前進
咱們常常會遇到看代碼時Ctrl+左鍵,層層跟蹤。而後迷失在代碼中的狀況,這時僅僅需要按「Alt+左方向鍵」就可以退回到上次閱讀的位置,同理,按「Alt+右方向鍵」會前進到剛纔退回的閱讀位置。就像瀏覽器的前進和後退button同樣。
三、Ctrl+Shift+o:本身主動導入包
四、Ctrl+Shift+r:打開資源
這多是所有快捷鍵組合中最省時間的了。
這組快捷鍵可以讓你打開你的工做區中不論什麼一個文件,而你僅僅需要按下文件名稱或mask名中的前幾個字母。比方applic*.xml。美中不足的是這組快捷鍵並非在所有視圖下都能用。
五、Ctrl+Shift+s:本身主動加入方法
可以加入一此set/get的方法,或toString等方法
六、Ctrl+Shift+/加入凝視,也可以用Ctrl+Shift+\取消凝視
七、Ctrl+o:高速outline
假設想要查看當前類的方法或某個特定方法,但又不想把代碼拉上拉下,也不想使用查找功能的話。就用ctrl+o吧。
它可以列出當前類中的所有方法及屬性,你僅僅需輸入你想要查詢的方法名,點擊enter就可以直接跳轉至你想去的位置。
八、ctrl+f:高速查找今天的Java IDE提供源代碼處理功能,Eclipse也是同樣。
現在,變量和方法的重命名變得十分簡單,你會習慣於在每次出現更好替代名稱的時候都作一次重命名。要使 用這個功能,將鼠標移動至屬性名或方法名上。按下alt+shift+r,輸入新名稱並點擊回車。就此完畢。
假設你重命名的是類中的一個屬性,你可以點擊alt+shift+r兩次。這會呼叫出源代碼處理對話框,可以實現get及set方法的本身主動重命名。
10.、ctrl+.及ctrl+1:下一個錯誤及高速改動
ctrl+.將光標移動至當前文件裏的下一個報錯處或警告處。這組快捷鍵我通常與ctrl+1一併使用,即改動建議的快捷鍵。
新版Eclipse的改動建 議作的很是不錯,可以幫你解決很是多問題,如方法中的缺失參數,throw/catch exception,未執行的方法等等
十一、高速複製一行
將光標放到某一行。按住Ctrl+Alt+Down,即可以在如下高速複製一行。按住Ctrl+Alt+Up,即可以在上面高速複製一行。
五、代碼質量工具
軟件開發是一個集體協做的過程,程序猿之間的代碼常常進行交換閱讀,所以。Java源程序有一些約定俗成的命名規定,主要目的是爲了提升Java程序的可讀性以及管理上的方便性。
好的程序代碼應首先易於閱讀。其次纔是效率高低的問題。
代碼凝視原則
1. 凝視應該簡單清晰,避免使用裝飾性內容。也就是說,不要使用象廣告橫幅那樣的凝視語句。
2. 代碼凝視的目的是要使代碼更易於被同一時候參與程序設計的開發人員以及其它後繼開發人員理解。
3. 先寫凝視。後寫代碼。
寫代碼凝視的最好方法是在寫代碼以前就寫凝視。這使你在寫代碼以前可以想一想代碼的功能和執行。並且這樣確保不會遺漏凝視。
(假設程序的邏輯略微複雜點的話,這樣作很是有效)
4. 凝視信息不只要包含代碼的功能,還應給出緣由。
好比,如下例 1 中的代碼顯示金額在 $1,000 以上(包含 $1,000)的定單可給予 5% 的折扣。
爲何要這樣作呢?難道有一個商業法則規定大額定單可以獲得折扣嗎?這樣的給大額定單的特殊是有時限的呢,仍是一直都這樣?最初的程序設計者是否僅僅是因爲大方大度才這樣作呢?除非它們在某個地方(或者是在源代碼自己。或者是在一個外部文檔裏)被凝視出來。不然你不可能知道這些。
if (grandTotal >= 1000.00)
{
grandTotal = grandTotal * 0.95;
}
更加具體的內容請看個人還有一個博文這裏:http://blog.csdn.net/evankaka/article/details/46538109
命名總體原則
1. 名字含義要明白,作到見名知義,如: User,Role, UserManager
2. 儘可能使用英文名字做爲變量名,假設要使用中文,請寫上備註.
如:var hbType = null;// hb是中文「貨幣」的首字母縮寫.
3. 採用大寫和小寫混合形式命名。提升名字的可讀性
正確:UserManager
錯誤: usermanager
4. 儘可能少用縮寫,但假設必定要使用,就要慎重地使用。
應該保留一個標準縮寫的列表,並且在使用時保持一致。好比,想對單詞「number」採用縮寫,使用 num 這樣的格式,並且僅僅使用這一種形式.注意:要維護縮寫詞彙列表.
5. 所有文件的名稱都是大寫字母開頭,大寫和小寫混合, 如UserList.jsp
6. 所有文件夾的名稱都是小寫字母開頭,大寫和小寫混合, 如userType
7. 變量名不能如下劃線開頭,如「_account」,」_userName」是不一樣意的,因爲下劃線開頭的變量可能被OWK平臺作爲保留字佔用.
8. 避免使用相似或者僅在大寫和小寫上有差異的名字
好比。不該同一時候使用變量名 persistentObject 和 persistentObjects。以及 anSqlDatabase 和 anSQLDatabase。
命名
包
包結構定義=${包單元}[.${包單元}]*
說明:
1:一個包是由一個或多個構造單元組成,各構造單元之間以點號」.」隔開
2:一個包單元由一個或多個詞組成
3:包單元應該是名詞
• 業務系統的包結構是com.cmb.zct.${業務系統名字}.${模塊名}
• 包名所有小寫,如:com.cmb.zct.tx.OA.common是不一樣意的.但有種狀況下贊成出現大寫字母,就是當包單元是由多個詞組成時.如: com.cmb.zct.tx.oa.userType.
類
• 使用全然的英文描寫敘述符,所有單詞的第一個字母要大寫,並且單詞中大寫和小寫混合。
• 類名是名詞或名詞詞組.如 LogManager
• 工具類以Util結尾 . 如FileUtil,StrUtil
• 異常類以Exception結尾.如RootDirNotExistsException
• 抽象類名以Abstract開頭 AbstractGenerator
• 工廠類以Factory結尾,如 ConnFactory
• 接口同類名。大寫和小寫混合..
方法
• 成員函數的命名應採用完整的英文描寫敘述符。大寫和小寫混合使用:所有中間單詞的第一個字母大寫。成員函數名稱的第一個單詞常常採用一個有強烈動做色彩的動詞。首個單詞小寫。如:getUserInfo, removeEquipment
參數變量
以 小寫p開頭
如
public void sendMessage(String pMessage){
...............
}
注意:javabean 的參數變量不帶p。
常量名
採用完整的英文大寫單詞,在詞與詞之間用下劃線鏈接。MAX_VALUE,DEFAULT_START_DATE
文件夾名
同包名。小寫字母開頭。假設有多個單詞構成,則第2個之後的單詞以大寫字母開頭。
如user, userType文件夾
文件名稱
同類名命名規則。大寫字母開頭,大寫和小寫混合。
如:EquipmentList.jsp
模塊相關文件命名約束。爲了方便說明。${MODEL_NAME}表明實際模塊的名稱,那各文件的名字必須知足下表格式要求.
文件 格式 舉例
業務組件接口 I${MODEL_NAME}Facade.java IUserFacade.java
服務組件接口 I${MODEL_NAME}Service.java IUserService.java
業務組件實現類 ${MODEL_NAME}FacadeImpl.java UserFacadeImpl.java
服務組件實現類 ${MODEL_NAME}ServiceImpl.java IUserServiceImpl.java
測試類 ${MODEL_NAME}ServiceTest.java UserServiceTest.java
更加具體的內容請看個人還有一個博文這裏:http://blog.csdn.net/evankaka/article/details/46538109
命名規範
一、 庫表名、字段名儘可能不用縮寫(英文單詞太長可適當縮寫,但要能讓人看明白含義,同一英語單詞的縮寫需保持一致)
二、 表名、字段名的各單詞間必須用下劃線分隔開
如 表名:USER_INFO 字段名:USER_CODE, USER_NAME
三、 必須爲每個子系統定義獨立的schema
代碼編寫規範
一、 對數據庫表、存儲過程的訪問必須顯示加上schema名稱(mysql也叫database);
二、 不一樣意使用select * from 編寫查詢語句。必須顯示寫查詢字段列表;
三、 不一樣意跨子系統直接訪問庫表,跨子系統必須經過服務接口進行調用;
四、 批量操做必須採用jdbc的batch方式提交。
五、 儘可能使用JDK自帶的API函數。不要本身寫相似功能的函數。
六、 Public方法中,對外部傳入的不可信任的參數。需要進行有效性校驗;
1. 避免顯式調用對象的toString方法
Object param1 = "param1"; // 顯式調用toString // 噹噹前日誌級別爲 info時。雖然沒有打印到文件裏,但是在方法調用參數傳遞時。已經作了一次toString的方法。 LOGGER.debug("打印一個參數:{}.", param1.toString()); // 正確的方式: LOGGER.debug("打印一個參數:{}.", param1);2. 對類中日誌工具對象logger應聲明爲static。
雖然一些logger對LogFactory工廠有一些優化。但是咱們也必須防止代碼沒有必要的執行。
3. 避免在循環中打印大量的日誌。
2.4.2 字符串處理
1. 對於常量字符串,不要經過new方式來建立;
2. 對於常量字符串之間的拼接。請使用「+」;對於字符串變量(不能在編譯期間肯定其具體值的字符串對象)之間的拼接,請使用StringBuilder/StringBuffer;
3. 在使用StringBuilder/StringBuffer進行字符串操做時,請儘可能設定初始容量大小;也儘可能避免經過String/CharSequence對象來構建StringBuffer對象(即:不要使用 new StringBuilder(String) 這個構造方法來建立StringBuilder對象);
4. 當查找字符串時,假設不需要支持正則表達式請使用indexOf(…)實現查找(特殊狀況可以使用startsWith和endsWith)。當需要支持正則表達式時。假設需要頻繁的進行查找匹配,請直接使用正則表達式工具類實現查找。
5. 儘可能避免使用String的split方法。
除非是必須的。不然應該避免使用split。split因爲支持正則表達式,因此效率比較低,假設是頻繁的幾十,幾百萬的調用將會耗費大量資源。假設確實 需要頻繁的調用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結果。
6.
1. 在循環外定義變量。
2. 對局部變量不需要顯式設置爲null。
3. 儘可能避免很是大的內存分配。
從數據庫中讀取的記錄放到集合中時,要注意控制集合元素個數。
4.
1. 數組的複製使用System.arraycopy(…)方法;
2. 對於數組、集合的拷貝、查找、排序等操做,假設是通常應用。可以優先採用java.util.Arrays和java.util.Collections 中提供的工具方法;但是對於熱點代碼。最好是參考java API中的方法實現,本身開發特定的排序等方法,以下降暫時對象的建立;
3. 當需要在方法之間傳遞多個屬性值時。從性能角度考慮,應優先採用結構體。而非ArrayList或Vector等集合類。
4. 在代碼開發中,需要依據應用場景合理選擇集合框架中的集合類,應用場景可按單線程和多線程來劃分,也可按頻繁插入、隨機提取等具體操做場景來劃分。
5. 定義集合對象時,請儘可能設定初始容量大小;
6.
1. 在IO操做中,必須定義finally代碼段,並在該代碼段中執行IO關閉操做。
2. 進行IO讀寫操做時,必須使用緩衝機制;
2.4.6 多線程處理
1. 避免太多的使用 synchronized keyword。
儘可能減少Synchronized的範圍。
2. 在線程池中執行的子線程,其run方法不可以往外拋出異常。
1. 避免在循環中對變量進行反覆計算
避免使用這類的語句:for(int i=0; i<list.size(); i++)
應該使用:int size=list.size(); for(int i=0; i<size; i++)
更加優化的是使用迭代的方式:for(Object o: list)
2. 異常僅僅能用於錯誤處理,不該該用來控制代碼流程
當建立一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用於描寫敘述異常是在何處建立的。
構建這些棧跟蹤時需要爲執行時棧作一份快照,正是這一部分開銷很是大。
當需要建立一個 Exception時,JVM不得不說:先別動。我想就您現在的樣子存一份快照,因此暫時中止入棧和出棧操做。
棧跟蹤不只僅包含執行時棧中的一兩個元素,而是包含這個棧中的每個元素。
日期處理主要完畢了一些格式方面的轉換
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.apache.commons.lang3.time.DateUtils; import com.google.common.primitives.UnsignedBytes; import com.lz.cts.common.errorcode.CtsErrorCode; import com.lz.ctsframework.core.support.ServiceException; /** * * <b>類說明:</b>日期工具類 * * <p> * <b>具體描寫敘述:</b> * * @author ***** * @since ***** */ public class CtsDateUtil { public final static String DATE_FROMAT = "yyyyMMdd"; public final static String TIME_FORMAT = "HHmmss"; /** * 兩個日期是否在跨度以內 * * @param startDate * @param endDate * @param gapType * 跨度類型。如Calendar.YEAR,Calendar.MONTH,Calendar.DAY_OF_YEAR * @param maxGap * 最大跨度值 * @return */ public static boolean isWithInDateGap(Date startDate, Date endDate, int gapType, int maxGap) { if (startDate == null) { throw new IllegalArgumentException("The startDate must not be null"); } if (endDate == null) { throw new IllegalArgumentException("The endDate must not be null"); } if (gapType != Calendar.YEAR && gapType != Calendar.MONTH && gapType != Calendar.DAY_OF_YEAR) { throw new IllegalArgumentException( "The value of gapType is invalid"); } Calendar start = Calendar.getInstance(); start.setTime(startDate); start.add(gapType, maxGap); int compare = start.getTime().compareTo(endDate); return compare >= 0; } /** * 兩個日期是否在跨度以內 * * @param startDate * @param endDate * @param gapType * 跨度類型,如Calendar.YEAR,Calendar.MONTH,Calendar.DAY_OF_YEAR * @param maxGap * 最大跨度值 * @return * @throws ParseException */ public static boolean isWithInDateGap(String startDate, String endDate, int gapType, int maxGap){ Date startDateTime = null; Date endDateTime = null; try{ startDateTime = DateUtils.parseDate(startDate, DATE_FROMAT); endDateTime = DateUtils.parseDate(endDate, DATE_FROMAT); }catch(ParseException e){ throw new ServiceException(*****,new String[]{"交易日期"}, "開始日期:" + startDate + ",結束日期:" + endDate); } return isWithInDateGap(startDateTime,endDateTime, gapType, maxGap); } /** * 兩個日期是否在跨度以內 * * @param startDate * @param endDate * @param gapType * 跨度類型,如Calendar.YEAR,Calendar.MONTH,Calendar.DAY_OF_YEAR * @param maxGap * 最大跨度值 * @return * @throws ParseException */ public static boolean isWithInDateGap(int startDate, int endDate, int gapType, int maxGap) throws ParseException { return isWithInDateGap( DateUtils.parseDate(String.valueOf(startDate), DATE_FROMAT), DateUtils.parseDate(String.valueOf(endDate), DATE_FROMAT), gapType, maxGap); } /** * <b>說明:</b> 獲取系統當前日期 * * @param * @return * @ * @author **** * @since 2014年5月22日 */ public static int getCurIntPcDate() { return Integer.parseInt(getCurPcDate()); } /** * <b>說明:</b> 獲取系統當前日期 * * @param * @return * @ * @author **** * @since **** */ public static String getCurPcDate() { java.util.Date currentDate = new java.util.Date(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT); return formatdate.format(currentDate); } /*** * <b>說明:</b> 獲取指定格式的系統當前日期 * @param * @return * @ * @author **** * @since **** */ public static String getCurPcDate(String strFormat) { java.util.Date currentDate = new java.util.Date(); SimpleDateFormat formatdate = new SimpleDateFormat(strFormat); return formatdate.format(currentDate); } /*** * <b>說明:</b> 獲取當時系統日期時間【YYYYMMDDHHmmss】 * @param * @return * @throws ServiceException * @author yanfy * @since 2014年6月5日 */ public static String getCurPcDateTime() { java.util.Date currentDate = new java.util.Date(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT+TIME_FORMAT); return formatdate.format(currentDate); } /** * <b>說明:</b> 獲取當時系統日期時間【YYYYMMDDHHmmss】 * @param * @return * @author **** * @since 2014年6月5日 */ public static Long getIntCurPcDateTime() { return Long.valueOf(getCurPcDateTime()); } /** * <b>說明:</b> 獲取系統當前時間 * * @param * @return 當前時間並格式化成「HHmmss」,如「123124」 * @ * @author **** * @since **** */ public static String getCurPcTime() { java.util.Date currentDate = new java.util.Date(); SimpleDateFormat formatdate = new SimpleDateFormat(TIME_FORMAT); return formatdate.format(currentDate); } /** * <b>說明: </b>驗證傳入數值型日期[YYYYMMDD]是否合法 * * @param * @return * @ * @author **** * @return * @since ***** */ public static boolean checkDateFormat(int intDate) { return checkDateFormat(String.valueOf(intDate)); } /** * <b>說明: </b>驗證傳入字符型日期[YYYYMMDD]是否合法 * * @param * @return * @ * @author **** * @since **** */ public static boolean checkDateFormat(String strDate) { return checkDateFormat(strDate, DATE_FROMAT); } /** * <b>說明: </b>驗證傳入字符型日期是否合法 * * @param * @return * @ * @author *** * @since **** */ public static boolean checkDateFormat(int intDate, String strFormat) { return checkDateFormat(String.valueOf(intDate), DATE_FROMAT); } /** * <b>說明: </b>驗證傳入字符型日期是否合法 * * @param * @return * @ * @author **** * @since *** */ public static boolean checkDateFormat(String strDate, String strFormat) { try { DateUtils.parseDateStrictly(strDate, strFormat); return true; } catch (ParseException e) { return false; } } /** * <b>說明: </b>驗證傳入數值型時間[HH24MMSS]是否合法 * * @param * @return * @ * @author **** * @return * @since **** */ public static boolean checkTimeFormat(int intDate) { String strDate = String.valueOf(intDate); if(strDate.length() <6) strDate = CommUtil.LeftFill(strDate, '0', 6); System.out.println("curTime:"+strDate); return checkTimeFormat(strDate); } /** * <b>說明: </b>驗證傳入字符型時間[HH24MMSS]是否合法 * * @param * @return * @ * @author **** * @since **** */ public static boolean checkTimeFormat(String strDate) { return checkTimeFormat(strDate, TIME_FORMAT); } /** * <b>說明: </b>驗證傳入字符型時間是否合法 * * @param * @return * @ * @author **** * @since **** */ public static boolean checkTimeFormat(int intDate, String strFormat) { return checkTimeFormat(String.valueOf(intDate), DATE_FROMAT); } /** * <b>說明: </b>驗證傳入字符型時間是否合法 * * @param * @return * @ * @author **** * @since *** */ public static boolean checkTimeFormat(String strDate, String strFormat){ try { DateUtils.parseDateStrictly(strDate, strFormat); return true; } catch (ParseException e) { return false; } } /** * <b>說明: </b>日期轉換 * @param strDate * @return */ public static Date parseDate(String strDate){ return parseDate(strDate, DATE_FROMAT); } /** * <b>說明: </b>日期轉換 * @param strDate * @param strFormat * @return */ public static Date parseDate(String strDate,String strFormat){ try { return DateUtils.parseDateStrictly(strDate, strFormat); } catch (ParseException e) { throw new ServiceException(CtsErrorCode.ERROR_FORMAT,new String[]{"交易日期"}, "日期:" + strDate); } } /** * <b>說明: </b>日期轉換 * @param intDate * @param strFormat * @return */ public static Date parseDate(int intDate,String strFormat){ return parseDate(String.valueOf(intDate), strFormat); } /** * <b>說明: </b>日期轉換 * @param intDate * @return */ public static Date parseDate(int intDate){ return parseDate(String.valueOf(intDate)); } /** * 日期轉換成字符串 * @param date * @param dateFormat * @return */ public static String date2String(Date date,String dateFormat) { SimpleDateFormat formatdate = new SimpleDateFormat(dateFormat); return formatdate.format(date); } /** * 日期轉換成字符串 * @param date * @param dateFormat * @return 格式爲YYYYMMDD */ public static String date2String(Date date) { return date2String(date,DATE_FROMAT); } /** * 日期轉換成整數 * @param date * @param dateFormat * @return 格式爲YYYYMMDD */ public static int date2Int(Date date) { String str = date2String(date,DATE_FROMAT); return Integer.parseInt(str); } /*** * <b>說明:</b> * @param * @return * @throws ServiceException * @author **** * @since *** */ public static String getCurrLastDay() { return getCurrAfterDay(1); } /*** * <b>說明:</b> * @param * @return * @throws ServiceException * @author **** * @since **** */ public static String getCurrAfterDay(int days) { Calendar theCa = Calendar.getInstance(); theCa.setTime(new Date()); theCa.add(theCa.DATE, -1*days); Date date = theCa.getTime(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT); return formatdate.format(date); } /** * 獲取交易日期以前的相隔天數的日期 * @param transDate 交易日期 * @param days 天數 * @return * @author **** * @since *** */ public static Integer getTransDateBeforeDay(Integer transDate,int days){ Calendar theCa = Calendar.getInstance(); theCa.setTime(parseDate(transDate)); theCa.add(Calendar.DATE, -1*days); Date date = theCa.getTime(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT); return Integer.valueOf(formatdate.format(date)); } /** * 獲取指定日期以後的相隔n年的日期 * @param transDate * @param years * @return * @return Integer */ public static Integer getDateAfterYear(Integer transDate, int years) { Calendar theCa = Calendar.getInstance(); theCa.setTime(parseDate(transDate)); theCa.add(Calendar.YEAR, years); Date date = theCa.getTime(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT); return Integer.valueOf(formatdate.format(date)); } /** * 獲取交易日期以後的相隔天數的日期 * @param transDate 交易日期 * @param days 天數 * @return * @author **** * @since **** */ public static Integer getTransDateAfterDay(Integer transDate,int days){ Calendar theCa = Calendar.getInstance(); theCa.setTime(parseDate(transDate)); theCa.add(Calendar.DATE, 1*days); Date date = theCa.getTime(); SimpleDateFormat formatdate = new SimpleDateFormat(DATE_FROMAT); return Integer.valueOf(formatdate.format(date)); } /** * 計算兩個日期相差的天數 * @param beginDate 【YYYYMMDD】 * @param endDate 【YYYYMMDD】 * @return Integer * @author **** * @since **** */ public static Integer diffDate(Integer beginDate,Integer endDate){ Calendar theCa1= Calendar.getInstance(); Calendar theCa2= Calendar.getInstance(); theCa1.setTime(parseDate(beginDate)); theCa2.setTime(parseDate(endDate)); long between_days=(theCa2.getTimeInMillis()-theCa1.getTimeInMillis())/(1000*3600*24); return Integer.parseInt(String.valueOf(between_days)); } }
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.MessageDigest; /** * MD5加密工具類 */ public class MD5EncoderUtil { private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; private static String algorithm = "MD5"; public static String encode(String salt, String rawPass) { return encode(rawPass.toLowerCase() + salt); } public static String encode(String rawPass) { String result = null; try { MessageDigest md5 = MessageDigest.getInstance(algorithm); // 加密後的字符串 result = byteArrayToHexString(md5.digest(rawPass.getBytes("utf-8"))); } catch (Exception ex) { ex.printStackTrace(); } return result; } public static String getFileMd5(File file) { FileInputStream fileInputStream = null; try { MessageDigest md5 = MessageDigest.getInstance(algorithm); fileInputStream = new FileInputStream(file); byte[] buffer = new byte[8192]; int length; while ((length = fileInputStream.read(buffer)) != -1) { md5.update(buffer, 0, length); } return byteArrayToHexString(md5.digest()); } catch (Exception e) { e.printStackTrace(); return null; } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static boolean isPasswordValid(String encPass, String loginName, String rawPass) { String pass1 = encPass; String pass2 = encode(loginName, rawPass); return pass1.toUpperCase().equals(pass2.toUpperCase()); } /* * 轉換字節數組爲16進制字串 */ private static String byteArrayToHexString(byte[] b) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) { resultSb.append(byteToHexString(b[i])); } return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n = 256 + n; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } }
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; import java.io.RandomAccessFile; import java.io.Reader; import java.io.Writer; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * <b>類說明:文件操做工具類</b> * * <p> * <b>具體描寫敘述:</b> * * @author ***** * @since ***** */ public class FileOperateAssistUtil { // 日誌記錄 private static Logger logger = LoggerFactory.getLogger(FileOperateAssistUtil.class); /** * * <b>方法說明:</b> 建立文件文件夾,若路徑存在,就不生成 * * <p> * <b>具體描寫敘述:</b> * * @param * @return * @author ***** * @since ***** */ public static void createDocDir(String dirName) { File file = new File(dirName); if (!file.exists()) { file.mkdirs(); } } /** * * <b>方法說明:</b> 建立文件文件夾 * * <p> * <b>具體描寫敘述:</b> * * @param * @return * @author ***** * @since ***** */ public static void isExistsMkDir(String dirName){ File file = new File(dirName); if (!file.exists()) { file.mkdirs(); } } /** * <b>方法說明:</b> 本地,在指定路徑生成文件。若文件存在,則刪除後重建。* * @param dirName * 本地路徑名, * @param file * 文件, * @return List<Object> * @throws ServiceException * @author ***** * @since ***** */ public static void creatFileByName(File file){ try { if (file.exists()) { file.delete(); logger.info("發現同名文件:{},先執行刪除。再新建。", file.getAbsolutePath()); } file.createNewFile(); logger.info("建立文件爲:{}", file.getAbsolutePath()); } catch (IOException e) { logger.error("建立{}文件失敗", file.getAbsolutePath(), e); } } /** * * <b>說明:</b> * <b>具體描寫敘述:建立新文件,若文件存在則刪除再建立。若不存在則直接建立</b> * @param * @returnType File * @since ***** * @author ***** */ public static File newFile(String fileName) { File file = new File(fileName); creatFileByName(file); return file; } /** * * <b>說明:</b> * <b>具體描寫敘述:關閉寫入流</b> * @param * @returnType void * @since ***** * @author ***** */ public static void closeWriter(Writer writer) { if (writer != null) { try { writer.close(); } catch (IOException e) { // throw new ServiceException(BatchErrorCode.FILE_CLOSE_EXCEPTION, e); logger.error("Close Writer cause Exception:", e); } } } /** * * <b>說明:</b> * <b>具體描寫敘述:關閉寫入流</b> * @param * @returnType void * @since ***** * @author ***** */ public static void closeReader(Reader reader) { if (reader != null) { try { reader.close(); } catch (IOException e) { logger.error("Close reader cause Exception:", e); } } } /** * * <b>說明:</b> * <b>具體描寫敘述:關閉隨機讀寫流</b> * @param * @returnType void * @since ***** * @author ***** */ public static void closeRandomAccessFile(RandomAccessFile raf){ if(raf != null){ try { raf.close(); }catch (IOException e) { throw new ServiceException(******,e, new String[]{"批量"}); } } } public static String getBatchNo(String transDate, Long i) { return transDate + getSerialNo(i); } public static String getFileBatchNo(String date) { if(StringUtils.isBlank(date)){ return CtsDateUtil.getCurPcDate(); } return date; } public static String getSerialNo(Long i) { return CommUtil.LeftFill(String.valueOf(i), '0', 3); } public static String getSerialNo(int i) { return CommUtil.LeftFill(String.valueOf(i), '0', 3); } /** * * <b>方法說明:</b> 建立控制文件 * * <p> * <b>具體描寫敘述:</b> * * @param * @return * @author ***** * @since***** */ public static void createControlFile(File dataFile, Long count) { String controlFileName = dataFile.getAbsolutePath().replace(".DAT", ".CTL"); File controlFile = null; BufferedWriter bw = null; try { controlFile = new File(controlFileName); if (controlFile.exists()) { controlFile.delete(); controlFile.createNewFile(); } // 獲取數據文件MD5 String dataFileMd5 = MD5EncoderUtil.getFileMd5(dataFile); StringBuilder controlFileContext = new StringBuilder().append(dataFile.getName()).append("\t") .append(dataFile.length()).append("\t").append(count.toString()).append("\t") .append(dataFileMd5 == null ?
"" : dataFileMd5); // 將MD5寫入控制文件 bw = new BufferedWriter(new FileWriter(controlFile, true)); bw.write(controlFileContext.toString()); bw.flush(); } catch (Exception e) { throw new ServiceException(*****, e, new String[]{"控制文件"}, "建立控制文件時發生異常"); } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { throw new ServiceException(*****, e, new String[]{"控制文件"}, "建立控制文件時發生異常"); } } } } /** * * <b>方法說明:</b> 校驗MD5 * * <p> * <b>具體描寫敘述:</b> * * @param * @return * @author ***** * @since ***** */ public static boolean md5Valid(File dataFile) throws ServiceException { String controlFileName = dataFile.getAbsolutePath().replace(".DAT", ".CTL"); // 獲取數據文件的MD5 String dataFileMd5 = MD5EncoderUtil.getFileMd5(dataFile); String controlFileMd5 = ""; BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(new File(controlFileName))); String tempString = reader.readLine(); // 獲取控制文件裏的MD5 if(StringUtils.isNotBlank(tempString)){ controlFileMd5 = tempString.substring(tempString.lastIndexOf("\t") + 1, tempString.length()); }else{ throw new ServiceException(CtsErrorCode.ERROR_VALIDATE_MD5, new String[]{"文件"}, "校驗文件MD5時發生異常"); } } catch (Exception e) { logger.error("校驗文件MD5時發生異常", e); throw new ServiceException(CtsErrorCode.ERROR_VALIDATE_MD5, e, new String[]{"文件"}, "校驗文件MD5時發生異常"); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { throw new ServiceException(CtsErrorCode.ERROR_VALIDATE_MD5, e, new String[]{"文件"}, "校驗文件MD5時發生異常"); } } } return dataFileMd5.toUpperCase().equals(controlFileMd5.toUpperCase()); } /** * <b>方法說明:</b> 將字符串拆解按特定標記解析,封裝爲String[] * * @param String * tempString 需要拆分的字符串 * @param String * tempString 拆分符號 * @param String * tempString 拆分符號出現次數 * @return List<Object> * @throws ServiceException * @author ***** * @since ***** */ public static String[] parseStringToStringArray(String tempString, String sign, int num) { List<Object> strlist = new ArrayList<Object>(); String[] strList = new String[num + 1]; try { int i; for (i = 0; i < num; i++) { String s1 = tempString.substring(0, tempString.indexOf(sign)).trim(); tempString = tempString.substring(tempString.indexOf(sign) + 1).trim(); strlist.add(s1); strList[i] = s1; if (i == num - 1) { strlist.add(tempString); strList[i + 1] = tempString; break; } } } catch (Exception e) { logger.error("解析還款清算文件失敗", e); throw new ServiceException(CtsErrorCode.ERROR_PARSE_FILE, e, new String[]{"還款清算"}, "解析還款清算文件失敗"); } return strList; } /** * * <b>方法說明:</b>格式化時間 * * <p> * <b>具體描寫敘述:</b> * * @param * @return * @author ***** * @since ***** */ public static String foamatTime(String transTime) { return CommUtil.LeftFill(transTime, '0', 6); } /** * <b>方法說明:</b> 上傳文件 * * @param transDate * 交易日期 * @param localPath * 本地路徑 * @param regName * 文件名稱前綴 * @param remotePath * 遠程路徑 * @return * @throws ServiceException * @author ***** * @since ***** */ public static Long uploadFiles(String transDate, String localPath, String regName, String remotePath) { SftpClient sftpClient = new SftpClient(); try { sftpClient.connect(); File[] fileList = listDataAndControlFile(localPath, regName + transDate); List<String> fileNameList = new ArrayList<String>(); Long count = 0L; for (File file : fileList) { count++; fileNameList.add(file.getAbsolutePath()); } if(count>0) sftpClient.uploadBatch(remotePath, fileNameList); return count; }finally { sftpClient.disConnect(); } } public static void uploadFile(String loaclpath, String fileName, String remotePath) { SftpClient sftpClient = new SftpClient(); try { File file = new File(loaclpath, fileName); sftpClient.upload(remotePath, file.getAbsolutePath()); }finally { sftpClient.disConnect(); } } public static void uploadFile(String loaclpath, List<String> fileName, String remotePath) { SftpClient sftpClient = new SftpClient(); try { List<String> fileNameList = new ArrayList<String>(); Long count = 0L; for (String item : fileName) { count++; fileNameList.add(loaclpath+"//"+item); } if(count>0) sftpClient.uploadBatch(remotePath, fileNameList); }finally { sftpClient.disConnect(); } } /*** * 依照指定格式分隔字符串 * @param tempString * @param splitChar * @return * @return String[] */ public static String[] splitString(String tempString,String splitChar) { String[] splits = (tempString.replace("||", "| | ") + (" ")).split(splitChar); for(int i=0;i<splits.length;i++){ if(null == splits[i]){ splits[i]=""; } } return splits; } public static String packProperty(String value) { if (value == null) { return ""; } return value.trim(); } public static String packProperty(Integer value) { if (value == null) { return ""; } return value.toString(); } public static String packProperty(BigDecimal value) { if (value == null) { return ""; } return value.toString(); } /** * * <b> 方法說明:</b><BR> * 獲取本地文件夾下過濾後的數據文件列表 * * @param localPath 要查詢的數據文件的路徑 * @param namePrefix 要過濾出來的數據文件前綴 * @return File[] 文件列表 * @author ***** */ public static File[] listDataFile(String localPath, final String namePrefix) { FilenameFilter nameFilter = new FilenameFilter() { @Override public boolean accept(File dir, String fileName) { return fileName.startsWith(namePrefix) && (fileName.endsWith(".DAT")); } }; File[] fileList = new File(localPath).listFiles(nameFilter); return fileList == null ? new File[0] : fileList; } /** * * <b>方法說明:</b> 獲取本地文件夾下過濾後的數據文件和控制文件列表 * * @param * @return * @author ***** * @since ***** */ public static File[] listDataAndControlFile(String localPath, String reg) { final String regName = reg; logger.debug("localPath:"+localPath+",reg:"+reg); FilenameFilter nameFilter = new FilenameFilter() { @Override public boolean accept(File dir, String fileName) { return fileName.indexOf(regName) >= 0 && (fileName.endsWith(".DAT") || fileName.endsWith(".CTL")); } }; File[] fileList = new File(localPath).listFiles(nameFilter); return fileList; } public static File[] deleteFilesFromDir(String localPath, String reg) { File[] oldFileList = FileOperateAssistUtil.listDataAndControlFile(localPath,reg); for (File file : oldFileList) { file.delete(); } return oldFileList; } public static String getBatchNoByFile(File file) { String fileName = file.getName(); String str = fileName.substring(fileName.lastIndexOf("_") + 1, fileName.lastIndexOf(".")); return str.length() <= 3 ? str : "001"; } }
package com.lz.ctsframework.core.support; import java.util.List; import org.apache.ibatis.annotations.Param; /** * * <b>類說明:</b>dao基類 * * <p> * <b>具體描寫敘述:</b> * * @author ** * @since *** */ public interface IBaseDao<T,E,K> { int countByCriteria(E criteria); int deleteByCriteria(E criteria); int deleteByPrimaryKey(K key); int insert(T entity); int insertSelective(T entity); List<T> selectByCriteria(E criteria); T selectByPrimaryKey(K key); int updateByCriteriaSelective(@Param("record") T entity, @Param("example") E criteria); //int updateByCriteria(@Param("record") T entity, @Param("example") E criteria); int updateByPrimaryKeySelective(T entity); //int updateByPrimaryKey(T entity); }
2.五、異常拋出類
package com.lz.ctsframework.core.support; import java.text.MessageFormat; /** * * <b>類說明:</b>Service層統一拋出的異常 * * <p> * <b>具體描寫敘述:</b> * * @author ***** * @since ***** */ public class ServiceException extends RuntimeException { private static final long serialVersionUID = 6514891174875747380L; /** 異常錯誤碼 **/ private String code; /** 異常描寫敘述 **/ private String msg; /** 擴展異常描寫敘述(包含msg) **/ private String extMsg; /** * ServiceException構造方法,有format字符組 * @param errorCode 錯誤碼 * @param param format字符組 * @param extMsg 擴展信息,給出具體的錯誤值信息等 */ public ServiceException(ErrorCode errorCode,String param[],String ... extMsg) { super(null==errorCode ? "" : errorCode.getCode()); init(errorCode, param,extMsg); } /** * ServiceException構造方法,有format字符組 * @param errCode * @param paramsList */ public ServiceException(ErrorCode errCode, Object... paramsList) { Object[] params = null; if ((paramsList != null) && (paramsList.length > 0) && ((paramsList[(paramsList.length - 1)] instanceof Throwable))) { Object[] newParam = new Object[paramsList.length - 1]; System.arraycopy(paramsList, 0, newParam, 0, newParam.length); params = newParam; super.initCause((Throwable)paramsList[(paramsList.length - 1)]); } else { params = paramsList; super.initCause(null); } this.code = null==errCode ?"" : errCode.getCode(); this.msg = null==errCode ? "" : MessageFormat.format(errCode.getMsg(),params); this.extMsg = this.msg; } private void init(ErrorCode errorCode, String param[], String... extMsg) { this.code = null==errorCode ? "" : errorCode.getCode(); this.msg = null==errorCode ? "" : MessageFormat.format(errorCode.getMsg(),param); StringBuilder builder = new StringBuilder(100); builder.append(this.msg); if(null != extMsg){ for(String ext : extMsg ){ builder.append("[").append(ext).append("]"); } } this.extMsg = builder.toString(); } /** * * @param code 錯誤碼 * @param msg 描寫敘述信息 */ public ServiceException(String code, String msg) { super(code+":"+msg); this.code = code; this.msg = msg; } /** * 帶Exception的構造方法,傳format字符數組 * @param errorCode 錯誤碼基類 * @param e 異常 * @param extMsg 擴展信息,給出具體的錯誤值信息等 */ public ServiceException(ErrorCode errorCode, Throwable e,String param[] , String ...extMsg ) { super(null==errorCode ? "" : errorCode.getCode(), e); init(errorCode, param, extMsg); } /** * * @param code 錯誤碼 * @param msg 描寫敘述信息 * @param e 異常 */ /*public ServiceException(String code, String msg,Throwable e) { super(code+":"+msg, e); this.code = code; this.msg = msg; }*/ /** * * * 方法說明:異常錯誤碼 * * @return */ public String getCode() { return code; } /** * * * 方法說明:異常描寫敘述信息 * * @return */ public String getMsg() { return msg; } public String getExtMsg() { return extMsg; } @Override public String getMessage() { return super.getMessage() + ","+extMsg; } public static void main(String[] args) { } }
import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; /** * * <b>類說明:</b>Jackson工具類 * * <p> * <b>具體描寫敘述:</b> * * @author **** * @since *** */ public class JacksonUtil { private static final ObjectMapper MAPPER = new ObjectMapper(); static { MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } private static final JsonFactory JSONFACTORY = new JsonFactory(); /** * 轉換Java Bean 爲 json */ public static String beanToJson(Object o) throws JsonParseException { StringWriter sw = new StringWriter(); JsonGenerator jsonGenerator = null; try { jsonGenerator = JSONFACTORY.createJsonGenerator(sw); MAPPER.writeValue(jsonGenerator, o); return sw.toString(); } catch (Exception e) { throw new RuntimeException(e+"轉換Java Bean 爲 json錯誤"); } finally { if (jsonGenerator != null) { try { jsonGenerator.close(); } catch (Exception e) { throw new RuntimeException(e+"轉換Java Bean 爲 json錯誤"); } } } } /** * json 轉 javabean * * @param json * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object jsonToBean(String json, Class clazz) throws JsonParseException { try { // MAPPER.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); return MAPPER.readValue(json, clazz); } catch (Exception e) { throw new RuntimeException(e+"json 轉 javabean錯誤"); } } /** * 轉換Java Bean 爲 HashMap */ @SuppressWarnings("unchecked") public static Map<String, Object> beanToMap(Object o) throws JsonParseException { try { return MAPPER.readValue(beanToJson(o), HashMap.class); } catch (Exception e) { throw new RuntimeException(e+"轉換Java Bean 爲 HashMap錯誤"); } } /** * 轉換Json String 爲 HashMap */ @SuppressWarnings("unchecked") public static Map<String, Object> jsonToMap(String json, boolean collToString) throws JsonParseException { Map<String, Object> map = null; try { map = MAPPER.readValue(json, HashMap.class); } catch (IOException e) { throw new RuntimeException(e+"轉換Java Bean 爲 HashMap錯誤"); } if (collToString) { for (Map.Entry<String, Object> entry : map.entrySet()) { if (entry.getValue() instanceof Collection || entry.getValue() instanceof Map) { entry.setValue(beanToJson(entry.getValue())); } } } return map; } /** * List 轉換成json * * @param list * @return */ public static String listToJson(List<Map<String, String>> list) throws JsonParseException { JsonGenerator jsonGenerator = null; StringWriter sw = new StringWriter(); try { jsonGenerator = JSONFACTORY.createJsonGenerator(sw); new ObjectMapper().writeValue(jsonGenerator, list); jsonGenerator.flush(); return sw.toString(); } catch (Exception e) { throw new RuntimeException(e+"List 轉換成json錯誤"); } finally { if (jsonGenerator != null) { try { jsonGenerator.flush(); jsonGenerator.close(); } catch (Exception e) { throw new RuntimeException(e+"List 轉換成json錯誤"); } } } } /** * json 轉List * * @param json * @return */ @SuppressWarnings("unchecked") public static List<Map<String, String>> jsonToList(String json) throws JsonParseException { try { if (json != null && !"".equals(json.trim())) { JsonParser jsonParse = JSONFACTORY.createJsonParser(new StringReader(json)); return (List<Map<String, String>>) new ObjectMapper().readValue(jsonParse, ArrayList.class); } else { throw new RuntimeException("json 轉List錯誤"); } } catch (Exception e) { throw new RuntimeException(e+"json 轉List錯誤"); } } }
也許有人看到這裏會以爲日誌不重要,因爲你們平時用得最多的預計就是System.out.prinln()之類的。這樣的方法對於小程序是沒問題。但是。對於一個完整的項目。有開發、有測試的。一方面。你假設開發過程當中,每個地方都要手動的輸出這些語句,豈不是很是麻煩。特別是使用Mybatis或Hibernate之類的框架,你想看看程序跑的時候,調用的SQL語句。
沒有日誌就很是難作到。
還有一方面,項目假設部署在server之上,測試人員在進行測試時,就沒法使用System.out.之類的語句來看輸出了。這時。統一的把程序執行的日誌輸出到一個文件裏去。而後經過一些linux的命令。就可以高速找到報錯的信息是什麼。
這裏興趣的同窗可以看我寫的:Log4j具體使用教程
一個典型的Log4j結構:
在小的項目中,可以日誌的做用沒那麼明顯。但是把日誌和框架結合起來用就非常常見。比方和Spring/mybatis/SprinMVC/Tomcat等的結合,打印出來的日誌可以例如如下,這裏日誌的格式可以本身來控制,以及日誌輸入的等級。如下是控制檯的輸出日誌
如下是輸出到外部的日誌文件
Maven還沒出現以前,每次新建一個Java或web項目,都得往編程路徑裏放很是多Jar包。
傳統引入jar的方式是將其放入web-inf->lib文件夾裏面,無形中增大了項目,並且jar不能統一進行管理。使用Maven的優勢之中的一個就是經過配置POM.XML文件本身主動下載jar包,並且經過中心庫統一進行管理、版本號的控制等。
一個典型的maven的web項目結構:
使用Maven的一些優勢
1. Maven的庫是由開源組織維護,不需要咱們再花精力去管第三方庫。即便本身維護,也比較方便。
2. Maven對jar包的版本號管理有工具上的支持,比方將Release版本號和Snapshot版本號區分開,有利於SCM管理。
3. Maven是標準。用過的人多,不需要額外培訓。
4. Maven的plugin比較多,可以有不少其它功能,Maven現有體系比較開放,採用的技術相對照較通用和成熟。plugin的機制也可以便於咱們擴展不少其它功能。
5. Maven的庫下載是即用即下,不需要實現所有down下來。
Maven的插件也是本身主動升級,可以方便的咱們擴展新功能。
6. 可以很是方便的與eclipse, IDEA這樣的主流的IDE集成
7. 版本號管理功能,這裏的版本號管理不是指第三方庫的版本號管理,而是項目的版本號管理
8. 網站功能:它的出現讓咱們可以對項目的狀態一目瞭然,可以本身主動的把項目的狀態和各類報表以網站的形式公佈到內部網或者外部網,可以隨時隨地查看項目狀態。有很是多中報表可以選擇。包含,doc生成。代碼規範的檢查,本身主動bug檢查。單元測試報表,單元測試的代碼覆蓋率報表。
總之,Maven做爲一個構建工具,不只幫咱們本身主動化構建,還能抽象構建過程,提供構建任務實現.他跨平臺,對外提供一致的操做接口,這一切足以使他成爲優秀的,流行的構建工具.
但是Maven不只是構建工具,他仍是一個依賴管理工具和項目信息管理工具.他還提供了中央倉庫,能幫咱們本身主動下載構件.
使用Maven還能享受一個額外的優勢,即Maven對於項目文件夾結構、測試用例命名方式等內容都有既定的規則,僅僅要遵循了這些成熟的規則,用戶在項目間切換的時候就免去了額外的學習成本,可以說是約定優於配置(Convention Over Configuration)。
Maven環境搭建
a)Apache Maven下載網站:http://maven.apache.org/download.html
b)maven的安裝
把Maven解壓到安裝文件夾後。需要設置兩個環境變量——PATH和M2_HOME。設置這兩個環境變量,假設Maven安裝文件夾是 c:\Program Files\maven-2.0.9,
打開-》計算機-》屬性-》高級系統設置-》環鏡變量
鍵入如下的命令:
下載下來以後,解壓,找個路徑放進去, 把bin的位置設在環境變量裏,新建環境變量MAVEN_HOME
c)驗證Maven安裝
因爲Maven依賴Java執行環境。所以使用Maven以前需要配置Java的執行環境。下載並安裝JDK。配置JDK的環境變量JAVA_HOME,不然maven將沒法使用
配置完畢後,在Windows命令提示符下,輸入mvn -v測試一下,配置成功顯示如圖:
具體看個人還有一博文http://blog.csdn.net/evankaka/article/details/47023955
SVN是Subversion的簡稱。是一個開放源代碼的版本號控制系統。相較於RCS、CVS,它採用了分支管理系統,它的設計目標就是代替CVS。
集中式管理的工做流程例如如下圖:
集中式代碼管理的核心是server。所有開發人員在開始新一天的工做以前必須從server獲代替碼,而後開發,最後解決衝突,提交。所有的版本號信息都放在server上。
假設脫離了server。開發人員基本上可以說是沒法工做的。如下舉例說明:
開始新一天的工做:
一、從server下載項目組最新代碼。
二、進入本身的分支,進行工做。每隔一個小時向server本身的分支提交一次代碼(很是多人都有這個習慣。因爲有時候本身對代碼改來改去,最後又想還原到前一個小時的版本號,或者看看前一個小時本身改動了哪些代碼,就需要這樣作了)。
三、下班時間快到了,把本身的分支合併到server主分支上。一天的工做完畢,並反映給server。
這就是經典的svn工做流程,從流程上看,有很多缺點。但也有優勢。
安裝
一、IDE中安裝SVN插件
Eclipse中安裝可以看,http://now51jq.blog.51cto.com/3474143/1571625
VS中可以安裝VisualSVN,它的下載地址:https://www.visualsvn.com/。
安裝過程:http://blog.csdn.net/lincyang/article/details/5658274(VS上還推薦安裝小番茄助手。很是強大的一個代碼提示插件)
二、TortoiseSVN
這是一個帶界面的SVN軟件。可以在windows上來使用。
有需要可以到http://tortoisesvn.net/來下載。
而後直接一路安裝就能夠。
一、NodePate++
可以用來打開各類文件。如java,xml、配置文件等等
二、DBVisualizer
DbVisualizer是一個全然基於JDBC的跨平臺數據庫管理工具,內置SQL語句編輯器(支持語法高亮),凡是具備JDBC數據庫接口的數據庫都可以管理,已經在Oracle, Sybase, DB2, Informix, MySQL, InstantDB, Cloudcape, HyperSonic ,Mimer SQL上經過測試
三、Fiddler
Fiddler是一個http協議調試代理工具,它可以記錄並檢查所有你的電腦和互聯網之間的http通信,設置斷點。查看所有的「進出」Fiddler的數據(指cookie,html,js,css等文件。這些都可以讓你胡亂改動的意思)。 Fiddler 要比其它的網絡調試器要更加簡單,因爲它不只僅暴露http通信還提供了一個用戶友好的格式。
四、SecureCRT
SecureCRT是一款支持SSH(SSH1和SSH2)的終端仿真程序。簡單地說是Windows下登陸UNIX或Linuxserver主機的軟件。
五、其它Eclipse插件編碼標準:CheckStyle 插件URL:http://eclipse-cs.sourceforge.net/update/代碼反覆:PMD的CPD 插件URL:http://pmd.sourceforge.net/eclipse/代碼覆蓋率:Eclemma 插件URL:http://update.eclemma.org依賴項分析:JDepend 插件URL:http://andrei.gmxhome.de/eclipse/複雜度分析:Eclipse Metric 插件URL:http://metrics.sourceforge.net/update