怎么解析一個xml字符串?我不是第一次看到有人問這個問題了..汗
1.使用StringReader
?

2.使用DocumentHelper.parseText()


3.最苯的方法:
?


posted @ 2007-02-06 12:39 dennis 閱讀(473) | 評論 (0) | 編輯 收藏
|
|||
怎么解析一個xml字符串?我不是第一次看到有人問這個問題了..汗 1.使用StringReader ? ![]() 2.使用DocumentHelper.parseText() ![]() ![]() 3.最苯的方法: ? ![]() ![]() posted @ 2007-02-06 12:39 dennis 閱讀(473) | 評論 (0) | 編輯 收藏 工作中還是一直使用jdk1.4.2版本,JDK5出來這么久也只是偶爾玩玩,特別是在學習EJB3時好好體驗了一把Annotation的便利. 枚舉類型也是JDK5引入的新的特性,看了幾篇文章,還是蠻有趣的. 過去我們定義常量,都是在一個專門的類或者接口中定義一大堆靜態常量類型,比如衣服的尺寸: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 然后這樣調用:Size.X,Size.M... 現在引入了枚舉類型,我們可以這樣定義: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 調用的方式不變,如:Size.S,Size.M...如果僅僅這樣的好處,好象還沒什么理由讓我們體驗到便利的一面,OK,讓我們談談enum的特性. 1.排序,枚舉類型默認按照原始排列的各個值元素的順序為依據,比如上面的例子:S<M<L<XX<XXX<XXL.默認提供compareTo()方法來比較: ? ![]() ?
2.通過values()來列舉所有的值,比如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 此例用到了JDK5的新特性,簡化的for循環 3.枚舉類型的集合:J2SE5提供了EnumMap<K extends Enum<K>,V>和EnumSet<E extends Enum<E>)兩個枚舉類型的集合類型,以map為例子: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? ...
4.給枚舉類型增加方法:枚舉類型可以像類那樣添加方法,假設大家在挑衣服的時候,常常不關心現在試的衣服的尺碼多少,而是簡單地獲取比當前的大一個級別的尺碼,我們給Size增加一個increase()方法: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 通過ordinal()方法找到當前的Size對象的值在整個Size值域中的位置,判斷位置是否是最大值,如果不是就再增長一個級別返回. 問題來了,如果我們希望Size的每個值都有一個test方法返回消息,而且消息都不一樣.那我們該如何處理.當然,我們可以像上面這樣: public String test(){ ..} 可以我們想實現更個性化的消息,比如"你好矮!...","你好胖..","你太高了吧!!!!"等等之類.首先我們給Size定義一個抽象方法: ? ![]() ? 然后就簡單了,每個值都實現自己的test方法: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? ?.... 漂亮吧,枚舉類型實在是個有趣的東東,當俺公司全面轉向J2SE5的時候可以好好玩一把 ?? posted @ 2007-02-06 12:37 dennis 閱讀(613) | 評論 (0) | 編輯 收藏 常用的幾個: ^[_/.0-9a-z-]+@([0-9a-z][0-9a-z-]+/.)+[a-z]{2,3}$
在JAVA中使用: ? import java.sql.*; public class test{ posted @ 2007-02-06 12:33 dennis 閱讀(3930) | 評論 (2) | 編輯 收藏 花了兩天時間,終于把jasperreport與項目中使用的hibernate結合使用.最新版本的ireport支持HQL查詢,可以在 ireport里面寫HQL語句查詢并設計好報表.需要注意的是把hibernate.cfg.xml包括進classpath!!(菜單options ->classpath進行設置)給張圖:
![]() 設計好報表之后編譯成jasper文件,在servlet中調用,我們需要實現自己的hibernate datasource: public class HibernateQueryResultDataSource implements JRDataSource { ?private String[] fields; ?private Iterator iterator; ?private Object currentValue; ?public HibernateQueryResultDataSource(List list, String[] fields) { ?public Object getFieldValue(JRField field) throws JRException { ?public boolean next() throws JRException { ?private int getFieldIndex(String field) { } 此類構造函數需要兩個參數,查詢結果的list以及查詢的所有屬性名(這些屬性名必須和報表界面的field名一致) ,使用方式如下: 1.導出pdf: File reportFile = new File(getServletContext().getRealPath( ??HibernateQueryResultDataSource dataSource = new HibernateQueryResultDataSource( ???} catch (Exception e) { 2.導出excel,需要把poi-2.0-final-20040126.jar放進web的lib里: try { ????JasperPrint print = JasperFillManager.fillReport( ????// jRXlsExporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, ????jRXlsExporter.exportReport(); ??? ???} catch (Exception e) { posted @ 2007-02-06 12:31 dennis 閱讀(3115) | 評論 (1) | 編輯 收藏 沒辦法直接設置可以采用變通手段來做:新建一個分組,組表達式寫成new Integer($V{COLUMN_COUNT}.intValue()/?),?號用你所需要的數字來代替,代表每頁記錄數
posted @ 2007-02-06 12:30 dennis 閱讀(659) | 評論 (0) | 編輯 收藏 ?項目已經上線,昨天客戶發現一個問題,某個操作取消不了,查看一下log,系統是websphere5.x,發現以下的異常:
E WLTC0033E: 在清除未解析 LocalTransactionContainment 時,資源 jdbc/oa回滾。 [07-1-15 17:37:09:280 CST] 57961377 LocalTranCoor E WLTC0032E: 一個或多個資源回滾。一個未解析的 LocalTransactionContainment 有一個未解析的回滾操作。 [07-1-15 17:37:09:280 CST] 57961377 WebAppTransac E WTRN0043I: 由于 setRollbackOnly,本地事務回滾。 [07-1-15 17:37:09:296 CST] 57961377 WebGroup????? E SRVE0026E: [Servlet 錯誤]-[LocalTransaction rolled-back due to setRollbackOnly]:com.ibm.ws.LocalTransaction.RolledbackException ??? at com.ibm.ws.LocalTransaction.LocalTranCoordImpl.cleanup(LocalTranCoordImpl.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.webapp.WebAppTransactionCollaborator.postInvoke(WebAppTransactionCollaborator.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java(Compiled Code)) ??? at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java(Compiled Code)) ??? at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java(Compiled Code)) ??? at com.ibm.ws.http.HttpConnection.run(HttpConnection.java(Compiled Code)) ??? at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code)) 查了下代碼,一開始沒發現有什么問題,不過是4,5個增刪操作(兩張表以上)。把錯誤信息輸入google搜索,挺多人碰到這個錯誤,有的說是websphere的bug,有的說要把AutoCommit設置為true. websphere的事務處理確實有bug,不過我們已經打過補丁,把AutoCommit設置為true的話,與我們所需要的效果不同,畢竟需要這些操作在同一個事務內。昨天查了一個晚上沒找到原因,今天一段一段地調試代碼,讓我發現問題了: conn = ConnectionManager.getConnection(); conn.setAutoCommit(false); 在conn.commit()前,我進行了一個判斷: if(....){ ? return; } conn.commit 直接return,導致后面的conn.commit()沒有執行,事務不完整。修改成: if(....){ ? ... ? conn.commit(); ? return; } 所以這個異常的出現,很有可能是你的事務處理有問題,那條教訓還是很有用的:一個方法最好不要有多個return語句。 posted @ 2007-02-06 12:27 dennis 閱讀(1281) | 評論 (0) | 編輯 收藏 ?這篇文章的想法來自于過去的兩篇文章:《設計自己的MVC框架》《設計模式之事務處理》
鏈接: http://www.javaresearch.org/article/59935.htm http://www.javaresearch.org/article/59043.htm 代碼下載同樣在www.126.com的郵箱里,用戶名 sharesources 密碼 javafans ??? 本文只是學習性質的文章,我一開始的想法就是修改《設計模式之事務處理》,提供Annotation來提供事務支持,支持到方法級別。通過引入一個 @Transaction標注,如果被此標注的方法將自動享受事務處理。目的是學習下Annotation和加深下對聲明式事務處理的理解。 ??? Annotation是JDK5引入的新特性,現在越來越多的框架采用此特性來代替煩瑣的xml配置文件,比如hibernate,ejb3, spring等。對Annotation不了解,請閱讀IBM網站上的文章,還有推薦javaeye的Annotation專欄:http: //www.javaeye.com/subject/Annotation ??? 代碼的示例是一個簡單的用戶管理例子。 ??? 首先,環境是mysql+jdk5+myeclipse5+tomcat5,在mysql中建立一張表adminusers: ??? create table adminusers(id int(10) auto_increment not null primary key, ???? name varchar(10) not null, ???? password varchar(10) not null, ???? user_type varchar(10)); ??? 然后在tomcat下建立一個數據源,把代碼中的strutslet.xml拷貝到tomcat安裝目錄下的 /conf/Catalina/localhost目錄里,請自行修改文件中的數據庫用戶名和密碼,以及數據庫名稱。另外,把mysql的 jdbc驅動拷貝到tomcat安裝目錄下的common/lib目錄。這樣數據源就建好了。在web.xml中引用: ?? <resource-ref> ??? ??? <description>DB Connection</description> ??? ??? <res-ref-name>jdbc/test</res-ref-name> ??? ??? <res-type>javax.sql.DataSource</res-type> ??? ??? <res-auth>Container</res-auth> ??? </resource-ref> ??? ??? 我的例子只是在《設計模式之事務處理》的基礎上改造的,在那篇文章里,我講解了自己對聲明式事務處理的理解,并利用動態代理實現了一個 TransactionWrapper(事務包裝器),通過業務代理工廠提供兩種版本的業務對象:經過事務包裝的和未經過事務包裝的。我們在默認情況下包裝業務對象中的所有方法,但實際情況是,業務對象中的很多方法不用跟數據庫打交道,它們根本不需要包裝在一個事務上下文中,這就引出了,我們為什么不提供一種方式來配置哪些方法需要事務控制而哪些并不需要?甚至提供事務隔離級別的聲明?很自然的想法就是提供一個配置文件,類似spring式的事務聲明。既然JDK5已經引入Annotation,相比于配置文件的煩瑣和容易出錯,我們定義一個@Transaction的annotation來提供此功能。 ??? 看下Transaction.java的代碼: ??? package com.strutslet.db; ??? import java.lang.annotation.Documented; ??? import java.lang.annotation.ElementType; ??? import java.lang.annotation.Retention; ??? import java.lang.annotation.RetentionPolicy; ??? import java.lang.annotation.Target; ??? import java.sql.Connection; ??? @Target(ElementType.METHOD) ??? @Retention(RetentionPolicy.RUNTIME) ??? @Documented ??? public @interface Transaction { ?? ? ? //事務隔離級別,默認為read_committed ?????? public int level() default Connection.TRANSACTION_READ_COMMITTED??? ; ??? } @Transaction 標注只有一個屬性level,level表示事務的隔離級別,默認為Read_Committed(也是一般JDBC驅動的默認級別,JDBC驅動默認級別一般于數據庫的隔離級別一致)。 @Target(ElementType.METHOD)表示此標注作用于方法級別, @Retention(RetentionPolicy.RUNTIME)表示在運行時,此標注的信息將被加載進JVM并可以通過Annotation的 API讀取。我們在運行時讀取Annotation的信息,根據隔離級別和被標注的方法名決定是否將業務對象的方法加進事務控制。我們只要稍微修改下 TransactionWrapper: //TransactionWrapper.java package com.strutslet.db; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import com.strutslet.exception.SystemException; public class TransactionWrapper { ??? ??? public static Object decorate(Object delegate) { ??? ??? return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), ??? ??? ??? ??? delegate.getClass().getInterfaces(), new XAWrapperHandler( ??? ??? ??? ??? ??? ??? delegate)); ??? } ??? static final class XAWrapperHandler implements InvocationHandler { ??? ??? private final Object delegate; ??? ??? XAWrapperHandler(Object delegate) { ??? ??? ??? // Cache the wrapped delegate, so we can pass method invocations ??? ??? ??? // to it. ??? ??? ??? this.delegate = delegate; ??? ??? } ??? ??? public Object invoke(Object proxy, Method method, Object[] args) ??? ??? ??? ??? throws Throwable { ??? ??? ??? Object result = null; ??? ??? ??? Connection con = ConnectionManager.getConnection(); ??????????? //得到Transaction標注 ??? ??? ??? Transaction transaction = method.getAnnotation(Transaction.class); ??? ??? ??? //如果不為空,說明代理對象調用的方法需要事務控制。 ??? ??? ??? if (transaction != null) { ??? ??? ??? ??? // System.out.println("transaction.." + con.toString()); ??? ??? ??? ??? // 得到事務隔離級別信息 ??? ??? ??? ??? int level = transaction.level(); ??? ??? ??? ??? try { ??? ??? ??? ??? ??? if (con.getAutoCommit()) ??? ??? ??? ??? ??? ??? con.setAutoCommit(false); ??????????????????? //設置事務隔離級別 ??? ??? ??? ??? ??? con.setTransactionIsolation(level); ??????????????????? //調用原始對象的業務方法 ??? ??? ??? ??? ??? result = method.invoke(delegate, args); ??? ??? ??? ??? ??? con.commit(); ??? ??? ??? ??? ??? con.setAutoCommit(true); ??? ??? ??? ??? } catch (SQLException se) { ??? ??? ??? ??? ??? // Rollback exception will be thrown by the invoke method ??? ??? ??? ??? ??? con.rollback(); ??? ??? ??? ??? ??? con.setAutoCommit(true); ??? ??? ??? ??? ??? throw new SystemException(se); ??? ??? ??? ??? } catch (Exception e) { ??? ??? ??? ??? ??? con.rollback(); ??? ??? ??? ??? ??? con.setAutoCommit(true); ??? ??? ??? ??? ??? throw new SystemException(e); ??? ??? ??? ??? } ??? ??? ??? } else { ??? ??? ??? ??? result = method.invoke(delegate, args); ??? ??? ??? } ??? ??? ??? return result; ??? ??? } ??? } } 現在,看下我們的UserManager業務接口,請注意,我們是使用動態代理,只能代理接口,所以要把@Transaction標注是接口中的業務方法(與EJB3中的Remote,Local接口類似的道理): package com.strutslet.demo.service; import java.sql.SQLException; import com.strutslet.db.Transaction; import com.strutslet.demo.domain.AdminUser; public interface UserManager { ??? //查詢,不需要事務控制 ??? public boolean checkUser(String name, String password) throws SQLException; ??? //新增一個用戶,需要事務控制,默認級別 ??? @Transaction ??? public boolean addUser(AdminUser user) throws SQLException; } 要把addUser改成其他事務隔離級別(比如oracle的serializable級別),稍微修改下:@Transaction(level=Connection.TRANSACTION_SERIALIZABLE) public boolean addUser(AdminUser user) throws SQLException; 不準備詳細解釋例子的業務流程,不過是登錄和增加用戶兩個業務方法,看下就明白。閱讀本文前最好已經讀過開頭提過的兩篇文章。我相信代碼是最好的解釋:) posted @ 2007-02-06 12:24 dennis 閱讀(1008) | 評論 (0) | 編輯 收藏 |
|||