使用比較
POI、jxl、jexcel可以劃歸為一類,通過java封裝了Excel的操作,所以需要折騰Workbook,Sheet,Cell等對(duì)象,顧及excel的每個(gè)細(xì)節(jié)。這種方式,優(yōu)點(diǎn)是功能強(qiáng)大。缺點(diǎn)是代碼冗長(zhǎng)拖沓,閱讀困難。
jxls雖然是基于POI,但其最大突破在于預(yù)先定制好Excel模板(如字段、格式、圖表等),運(yùn)行期綁定數(shù)據(jù)即可呈現(xiàn)多樣化報(bào)表。其優(yōu)點(diǎn)是編程輕松,功能靈活方便。缺點(diǎn)是對(duì)于過于動(dòng)態(tài)化報(bào)表不太適用(如輸出字段、格式非常多變)。
Jacob和COM模型粘在一起,自然被純java的擁躉者所不顧。所以,應(yīng)用不是很廣。
jxls初體驗(yàn)
業(yè)務(wù)部門經(jīng)常需要我們技術(shù)部給推送一些定期報(bào)表,這些報(bào)表的字段及格式都是預(yù)定義好的。顯而易見,在這種場(chǎng)合,jxls是再適合不過的工具了。只要定義好
輸出報(bào)表的模板,綁定查詢出的數(shù)據(jù)即大功告成。日常維護(hù)起來也很方便,比如加減字段、改變展現(xiàn)方式、嵌入excel自動(dòng)圖表等都能輕松搞定。
百聞不如一見,從jxls主頁[5]上下載了jXLS
v.0.9.6(不知何故,自20080409日后沒有再更新),安裝起來運(yùn)行其中自帶的范例。自帶范例可以通過maven來編譯,偶試了試編譯成功,但
不知道怎么運(yùn)行范例。后來沒轍,把范例導(dǎo)到eclipse中進(jìn)行編譯運(yùn)行。編譯時(shí)下載了最新的poi-3.2-FINAL-20081019.jar,結(jié)
果編譯成功,但運(yùn)行報(bào)錯(cuò)
java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFCell.setEncoding(S)V
后來換成poi-3.1-FINAL-20080629.jar,又報(bào)別的錯(cuò),最后好不容易從CSDN上下載了poi-3.0.1-FINAL-
200705.jar,總算運(yùn)行成功。體驗(yàn)了一下,效果非常好。讓人不解的是,在POI主站上只能下載到最新的POI3.2版本,老版本就是找不到。
參考資料
1、http://schmidt.devlib.org/java/libraries-excel.html,java操作Excel的類庫清單
2、http://jakarta.apache.org/poi/,POI主頁
3、http://www.andykhan.com/jexcelapi/index.html,jxl主頁
4、http://www.teamdev.com/jexcel/index.jsf,jexcel主頁。
5、http://jxls.sourceforge.net/,jxls主頁
6、http://jacob-project.wiki.sourceforge.net/,Jacob主頁
1、
org.springframework.orm.ObjectRetrievalFailureException: Object of class [com.xindeco.myregister.pojo.MyRegisterInfo] with identifier [14]: not found
MyRegisterInfo在數(shù)據(jù)庫沒有identifier [14]對(duì)象。
2、
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.xindeco.myregister.pojo.MyRegisterInfo column: password (should be mapped with insert="false" update="false")
出錯(cuò)原因:password 和repassword同時(shí)對(duì)應(yīng)數(shù)據(jù)庫表中的password一列,同時(shí)update和insert都設(shè)為true。
xml文件如下:
<property name="password"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="password"
length = "32"
/>
<property name="repassword"
type="java.lang.String"
update="false"
insert="false"
access="property"
column="password"
length = "32"
/>
解決的方法:
將repassword的insert和update設(shè)為false。
3、
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed;
nested exception is org.hibernate.PropertyNotFoundException: Could not find a getter for ID in class
錯(cuò)誤原因:hibernate的映射文件中ID是大寫的,而pojo的類中id是小寫的
注意事項(xiàng):每個(gè)pojo的類都要繼承abstractEntity,其中abstractEntity類有個(gè)ID的屬性要重寫
public abstract class AbstractEntity
implements Entity, BaseDTO {
abstract public long getID();
abstract public void setID(long id);
public int hashCode() {
return (int)this.getID();
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Entity) {
return this.getID() == ( (Entity) obj).getID();
}
return false;
}
}
4、
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
錯(cuò)誤原因:
在application.xml文件中deleteRegister方法以delete開頭,并沒有被設(shè)定為可更改的,應(yīng)如下設(shè)置:
<!--為事物創(chuàng)建代理類,并指定方法的事物類型-->
<bean id="baseTxProxy" lazy-init="true" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="cancel*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
加上一行
<prop key="delete*">PROPAGATION_REQUIRED</prop>
5、
ERROR org.apache.struts.util.RequestUtils - Error creating form bean of class com.xindeco.business.web.form.GraAppInfoForm
public class GraAppInfoForm
extends ActionForm 錯(cuò)誤寫成
public abstratic class GraAppInfoForm
extends ActionForm
6、
2006-04-25 08:56:38,495 ERROR com.xindeco.business.web.action.GraAppAction - com.xindeco.business.web.action.GraAppAction@8e2fb5
java.lang.ClassCastException: $Proxy0
at com.xindeco.business.web.action.GraAppAction.newone(GraAppAction.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)
at com.xindeco.core.web.action.BaseAction.dispatchMethod(BaseAction.java:153)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)
actioin類中的newone方法如下:
public class GraAppAction
extends BaseAction {
public ActionForward newone(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
GraAppService graservice = (GraAppService) this.getBean("GraAppService");
}
applicationcontext中的GraAppService的配置如下:
<bean id="GraAppDAO" class="com.xindeco.business.dao.impl.GraAppDAOImpl">
<property name="support">
<ref local="support"/>
</property>
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="GraAppService" parent="baseTxProxy">
<property name="target">
<bean class="com.xindeco.business.service.impl.GraAppServiceImpl" autowire="byName">
<property name="baseDAO">
<ref bean="GraAppDAO"/>
</property>
</bean>
</property>
</bean>
因此this.getBean("GraAppService");是為了得到GraAppServicImpl類的實(shí)現(xiàn)。GraAppService是interface
public class GraAppServiceImpl extends BaseServiceImpl
implements GraAppService{
}
7、org.hibernate.hql.ast.QuerySyntaxException: Demand is not mapped. [from Demand where unitid = ? and needNum > usedNeedNum]
hibernate.cfg.xml沒有配置Demand.hbm.xml文件的目錄
8、org.springframework.jdbc.BadSqlGrammarException: Bad SQL grammar [] in task 'Hibernate operation'; nested exception is java.sql.SQLException: 列名 'id' 無效。
java.sql.SQLException: 列名 'name' 無效。
因?yàn)閔ibernate聲明的id,name的columnid屬性沒有與數(shù)據(jù)庫的字段對(duì)應(yīng),所以id,name無效。
9、java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:415)
at java.lang.Integer.parseInt(Integer.java:497)
at com.xindeco.business.service.impl.DemandServiceImpl.findDemandListByUnitId(DemandServiceImpl.java:33)
錯(cuò)誤語句為
needNum = Integer.parseInt(demand.getNeedNum());
usedNeedNum = Integer.parseInt(demand.getUsedNeedNum());
因?yàn)閐emand.getUsedNeedNum()==null,無法轉(zhuǎn)化為string 類型,
10、rg.apache.jasper.JasperException: /GraAppInfo/GraAppInfoNew.jsp(343,29) According to TLD, tag bean:write must be empty, but is not
錯(cuò)誤的原因:
<select name="politicsID" >
<option value="">請(qǐng)選擇</option>
<logic:notEmpty name="politicsList">
<logic:iterate id="politics" name="politicsList">
</logic:notEmpty>
<option value="<bean:write name="politics" property="codeID"/>"><bean:write name="politics" property="codeName"/></option>
</logic:iterate>
</select>
就因?yàn)樯倭?>
以后懂得通過查找字?jǐn)?shù),來檢查錯(cuò)誤
11、2006-04-26 13:27:54,812 ERROR com.xindeco.core.util.BeanUtils - bean property [Nation] copy failed
com.xindeco.core.exception.ConvertException: org.springframework.orm.hibernate3.HibernateSystemException: Unknown entity: java.lang.String; nested exception is org.hibernate.MappingException: Unknown entity: java.lang.String
beanUtil.beanCopy(grapojo,form,BizConstants.CONVERTER);
要求:
1、pojo類的屬性只有與form屬性名字相同,才能beancopy成功
2、pojo中屬性是實(shí)體,在form中一定要用int,long表示
出現(xiàn)這錯(cuò)誤的原因是pojo中的屬性不是實(shí)體,而錯(cuò)誤寫成:
string
private String nation;應(yīng)改成 private Syscode nation;
12、
2006-04-26 14:38:37,843 ERROR com.xindeco.business.web.action.GraAppAction - com.xindeco.business.web.action.GraAppAction@fa1b2d
java.lang.NullPointerException
at com.xindeco.business.web.action.GraAppAction.newone(GraAppAction.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
hibernate配置文件沒改,程序找不到相應(yīng)的類
<many-to-one
name="FSUnit"
class="com.xindeco.business.pojo.EmployUnitBaseInfo"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="fSUnit"
/>
其實(shí)FSUnit對(duì)應(yīng)的類應(yīng)該是FSUnit
<many-to-one
name="FSUnit"
class="com.xindeco.business.pojo.FSUnit"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="fSUnit"
/>
13、
org.hibernate.MappingException: An association from the table GraAppInfo refers to an unmapped class: com.xindeco.business.pojo.FSUnit
錯(cuò)誤原因:hibernate.cfg.xml沒有配置fsunit.hbm.xml文件的位置
14、
java.lang.ClassCastException: com.xindeco.business.dao.impl.GraAppDAOImpl
at com.xindeco.business.service.impl.GraAppServiceImpl.addGraduateApp(GraAppServiceImpl.java:16)
GraAppServiceImpl.java:16
第16行: GraAppDAO dao = (GraAppDAO) this.getBaseDAO();//其實(shí)得到的是GraAppDAOImpl
錯(cuò)誤的原因是
public class GraAppDAOImpl
extends BaseDAOImpl {
}
沒有實(shí)現(xiàn)GraAppDAO接口,正確的做法是
public class GraAppDAOImpl
extends BaseDAOImpl implements GraAppDAO {
}
先繼承后實(shí)現(xiàn)
15、2006-04-27 08:38:54,078 ERROR com.xindeco.business.web.action.GraAppAction - com.xindeco.business.web.action.GraAppAction@1d6399b
java.lang.ClassCastException: com.xindeco.business.pojo.SysCode
at org.hibernate.type.StringType.set(StringType.java:26)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:63)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:40)
一般是因?yàn)閔ibernate聲明類型和pojo類聲明的類型不一樣,并且前面已經(jīng)出現(xiàn)了Hibernate: insert into TGraAppInfo (name, whereFrom, degree, college, speciality, studentRelTel, remark, higherEduLength, highSchool, studyResume, normalOrNot, proxyUnit, workPost, workPlace, studentAddress, studentPostNumber, nation, appStatus) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
的操作提示,查出錯(cuò)誤的原因有:
<many-to-one
name="demand"
class="com.xindeco.business.pojo.Syscode"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="demandID"
/>
<property
name="appStatus"
type="int"
update="true"
insert="true"
access="property"
column="appStatus"
length="10"
/>
應(yīng)改為
<many-to-one
name="demand"
class="com.xindeco.business.pojo.Demand"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="demandID"
/>
<many-to-one
name="nation"
class="com.xindeco.business.pojo.SysCode"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="nation"
/>
16、
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.xindeco.business.pojo.SysCode
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:626)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:570)
at
org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:482)
pojo類為:
public class GraAppInfo{
private College college;
}
action 類為
public class GraAppAction
extends BaseAction {
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
graInfo.setCollege(new College());\\必須從數(shù)據(jù)庫找到college這個(gè)對(duì)象,而不能新生成
graInfo.getCollege().setID(graForm.getCollegeID());
graInfo.setAppStatus(Integer.parseInt("0"));
service.addGraduateApp(graInfo);
}
public class GraAppServiceImpl extends BaseServiceImpl
implements GraAppService{
public boolean addGraduateApp(GraAppInfo info){
this.getBaseDAO().save(info);
return true;
}
}
dao類save方法為
getHibernateTemplate().save(obj);
當(dāng)cascade="all",插入new college 除了id和原來的記錄一樣,其他的字段全部都被更新,為null
當(dāng)cascase=“insert”,插入new college 只會(huì)把它的id插入grainfo表中,其他字段不變。
17、java.sql.SQLException: Unable to convert between java.lang.Integer and BLOB.
因?yàn)?/p>
<property
name="province"
type="com.xindeco.business.pojo.SysCode"http://不能用復(fù)雜類,
update="true"
insert="true"
access="property"
column="provinceId"
/>
應(yīng)該改為
<many-to-one
name="province"
class="com.xindeco.business.pojo.SysCode"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="provinceId"
/>
18、javax.servlet.jsp.JspException: Cannot create iterator for this collection
at org.apache.struts.taglib.logic.IterateTag.doStartTag(IterateTag.java:265)
jsp文件如下:
<logic:notEmpty name="graduateList" >
<logic:iterate id="graduate" name="graduateList" >
</ogic:notEmpty >
</ogic:iterat>
graduateList是一個(gè)類,而logic:iterator要求必須是ArrayList,HashSet....這樣的集合類,而graduateList中一個(gè)屬性是ArrayList或HashSet的
應(yīng)改為:
<logic:notEmpty name="graduateList" property="items">
<logic:iterate id="graduate" name="graduateList" property="items" >
</ogic:notEmpty >
</ogic:iterat>
19、2006-05-11 17:13:37,468 ERROR com.xindeco.business.web.action.GraAppAction - com.xindeco.business.web.action.GraAppAction@bc22eb
org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
SysUser user= (SysUser) request.getSession().getAttribute(WebConstants.SESSION_USER);
System.out.println(user.getRole().getRoleName());
當(dāng)hibernate session取出數(shù)據(jù)放到http session時(shí),
由于sysuser中role的lazy=“true”,所以沒有將RoleName放到http session中,當(dāng)System.out.println(user.getRole().getRoleName());
時(shí),雖然http session還開著, hibernat seesion已經(jīng)關(guān)閉
<many-to-one
name="role"
class="com.xindeco.business.pojo.SysRole"
lazy="false"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="roleID"
/>
20、Association references unmapped class: com.xindeco.workflow.WFNode
因?yàn)閍pplication.xml文件中沒有配置<mapping resource="com/xindeco/workflow/WFNode.hbm.xml"/>
系統(tǒng)找不到WFNode
< set
name = " nodes "
table = " WF_ROLENODES "
lazy = " true "
inverse = " false "
cascade = " none "
sort = " unsorted "
>
< key column = " roleID " > </ key >
< many - to - many
class = " com.xindeco.workflow.WFNode "
column = " nodeId "
outer - join = " auto " />
</ set >
我們經(jīng)常用的就是擴(kuò)展它的接口ApplicationContext.而它的實(shí)現(xiàn)又有多種,我們只介紹一些常用的實(shí)現(xiàn)。applicationContext.xml文件是位于Src目錄下。今天看到網(wǎng)上有轉(zhuǎn)載的獲得Spring Bean的方法,覺得值得珍藏,現(xiàn)摘錄在此。
眾所周知,Spring框架將DI模式發(fā)揮到了極至,因此,系統(tǒng)里面用Spring管理的Bean相互之間的獲取是非常
方便的,只要使用者提供一個(gè)setter方法并在配置文件中配置該屬性就可以。
但是,對(duì)于系統(tǒng)中非Spring框架管理的類,如果需要獲取Spring管理的類,或者,程序中需要?jiǎng)討B(tài)的根據(jù)Be
an的id來獲取Bean實(shí)例,不可能事先為該類提供所有需要的Bean屬性的setter方法,在類似這樣的情況下,
獲取Spring框架管理的類實(shí)例的方法有多種,現(xiàn)在簡(jiǎn)單總結(jié)如下:
方法一:在初始化時(shí)保存ApplicationContext對(duì)象
代碼:
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
說明:
這種方式適用于采用Spring框架的獨(dú)立應(yīng)用程序,需要程序通過配置文件手工初始化Spring的情況。
方法二:通過Spring提供的工具類獲取ApplicationContext對(duì)象
代碼:
import org.springframework.web.context.support.WebApplicationContextUtils;
ApplicationContext ac1 =
WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc)
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
ac1.getBean("beanId");
ac2.getBean("beanId");
說明:
這種方式適合于采用Spring框架的B/S系統(tǒng),通過ServletContext對(duì)象獲取ApplicationContext對(duì)象,然后
在通過它獲取需要的類實(shí)例。
上面兩個(gè)工具方式的區(qū)別是,前者在獲取失敗時(shí)拋出異常,后者返回null。
方法三:繼承自抽象類ApplicationObjectSupport
說明:
抽象類ApplicationObjectSupport提供getApplicationContext()方法,可以方便的獲取到ApplicationContext。Spring初始化時(shí),會(huì)通過該抽象類的setApplicationContext(ApplicationContext context)方法將ApplicationContext 對(duì)象注入。
方法四:繼承自抽象類WebApplicationObjectSupport
說明:
類似上面方法,調(diào)用getWebApplicationContext()獲取WebApplicationContext
方法五:實(shí)現(xiàn)接口ApplicationContextAware
說明:
實(shí)現(xiàn)該接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 對(duì)象。Spring初始化時(shí),會(huì)通過該方法將ApplicationContext 對(duì)象注入。
以上方法適合不同的情況,請(qǐng)根據(jù)具體情況選用相應(yīng)的方法。
這里值得提一點(diǎn)的是,系統(tǒng)中用到上述方法的類實(shí)際上就于Spring框架緊密耦合在一起了,因?yàn)檫@些類是知
道它們是運(yùn)行在Spring框架上的,因此,系統(tǒng)中,應(yīng)該盡量的減少這類應(yīng)用,使系統(tǒng)盡可能的獨(dú)立于當(dāng)前運(yùn)
行環(huán)境,盡量通過DI的方式獲取需要的服務(wù)提供者。
方法五比較可行,可以設(shè)計(jì)一個(gè)工具類,專門來獲取Spring中的類。減少對(duì)業(yè)務(wù)代碼的侵入性。