2007年5月7日
错误信息如下:
java.lang.NoClassDefFoundError: sun.management.ManagementFactory
处理:
把sun.management.ManagementFactory替换成java.lang.management.ManagementFactory
因为ibm的jdk没有sun.management.ManagementFactory这个对象
错误信息如下:
超过最大长度限制
处理:
只能插入666个中文字符。
或者更新到最新的oracle驱动包
1:derby.jar包可能冲突,需删除项目中的该包
2:MBean调用问题
Websphere的MBean注册路径包括cell,nodeName和processName,具体可以铜鼓jconsole连接来查看MBean注册的全路径。这三个值可以通过Websphere的com.ibm.websphere.management.AdminServiceFactory这个对象来获取,spring中的配置如下:
<!--
用于获取websphere的MBean名称的cell,node,process -->
<bean id="adminService" class="com.ibm.websphere.management.AdminServiceFactory" factory-method="getAdminService"/>
<bean id="adminService.cellName" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
<bean id="adminService.nodeName" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
<bean id="adminService.processName" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
<bean id="websphereNamingStrategy" class="com.des.engine.mbean.WebsphereNamingStrategy">
<property name="cellName" ref="adminService.cellName"/>
<property name="nodeName" ref="adminService.nodeName"/>
<property name="processName" ref="adminService.processName"/>
</bean>
WebsphereNamingStrategy为自己创建的对象就包括那三个属性
3:安全问题
出现如下错误,Caused by: javax.management.JMRuntimeException: ADMN0022E: 由于凭证不足或凭证为空,无法对 org.apache.servicemix:Name=ServiceMgtImpl,cell=dvpbNode02Cell,Type=SystemService,ContainerName=ServiceMix,node=dvpbNode02,process=server1 MBean 的 retrieveServiceList 操作进行访问。
该问题是因为设置了安全控制,把控制台的【安全性->安全管理、应用程序和基础结构】里面的所以安全配置都去掉,然后重新启动服务器主机(注意是重启主机,不然安全设置不起作用),再启动websphere服务应该就可以了,还有就是servicemix的应用要跟websphere一起启动,不要等websphere启动后再到控制台启动
错误信息如下:
jdbc在操作oracle海量数据的时候用ResultSet获取所有的返回数据出现内存溢出
处理:
出错的原因是ResultSet用的是可滚动结果集,正常情况下ResultSet是指针指向数据库的数据,本身是不存储数据库的数据的,默认情况下就算是提交的sql能查询处上亿条的数据也是不消耗内存的,但是如果用的是可滚动结果集的ResultSet情况就不一样了,ORACLE 是不支持可滚动结果集的,那么我们用JDBC得到一个可滚动的结果集就是由JDBC自己支持的,也就是说结果集是要存放在内存中的,所以在海量数据的情况下也就是要消耗大量内存的,因此造成内存溢出也就是正常的了,所以如果是海量数据的话就不要用可滚动结果集就可以了。
错误信息如下:
com.ibm.websphere.ce.cm.StaleConnectionException: [ibm][db2][jcc][t4][2030][11211]
检测到了通信错误。所使用的通信协议:TCP/IP。"n所使用的通信 API:SOCKETS。
检测到错误的位置:Reply.fill()。"n用于检测错误的通信功能:InputStream.read()。
特定于协议的错误代码数据不足、* 和 0。消息:null"n
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)"n
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:67)"n at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance
(DelegatingConstructorAccessorImpl.java:45)"n
at java.lang.reflect.Constructor.newInstance(Constructor.java:522)"n
at com.ibm.websphere.rsadapter.GenericDataStoreHelper.mapExceptionHelper
(GenericDataStoreHelper.java:523)"n
at com.ibm.websphere.rsadapter.GenericDataStoreHelper.mapException(GenericDataStoreHelper.java:578)"n
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.mapException(WSJdbcUtil.java:909)"n
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeQuery(WSJdbcStatement.java:898)"n
at com.newland.bi.util.db.DBUtil.executeQuery(Unknown Source)"n
at com.newland.bi.util.db.DBUtil.executeSql(Unknown Source)"n
at com.newland.bi.dao.jdbc.DaoImpl.executeQuery(DaoImpl.java:64)"n
at com.newland.bi.service.report.exp.dao.ReportExpDao.getExpList(ReportExpDao.java:72)"n
at com.newland.bi.service.report.exp.manage.ReportExpMgt.runExport(ReportExpMgt.java:91)"n
at com.newland.bi.service.report.exp.servlet.ReportExp1Servlet$1.run(ReportExp1Servlet.java:97)"n
at java.util.TimerThread.mainLoop(Timer.java:537)"n at java.util.TimerThread.run(Timer.java:487)"n
处理:
出错的原因可能是防火墙问题,在websphere应用服务器和数据库服务器之间是否存在防火墙
防火墙是否会设置多久没活动的连接就自动断开掉,如果是这样的话就会有问题,因为websphere上面的数据库连接池可能有一段时间没连接而被防火墙断掉了
但对于连接池本身根本就不知道该连接是否还可用,所以web应用从连接池获取的连接可能就是已经断开的了,所以就可能会出现日记中的错误问题
schedule和scheduleAtFixedRate的区别在于,如果指定开始执行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上。
错误信息如下:
Caused by: java.lang.ClassNotFoundException: org.apache.axis.soap.MessageFactoryImpl
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at javax.xml.soap.MessageFactory.newInstance(MessageFactory.java:50)
... 10 more
处理:
原因是调用了axis的 soap.MessageFactoryImpl,cxf应该用的是sun的
在注册安全拦截器之前执行下面代码就可以了
System.setProperty("javax.xml.soap.MessageFactory", "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl");
我们写程序的时候可能会想用open或者<a>来下载一个txt文件,但我们会发现我们用浏览器下载这个txt文件的时候老是在浏览器里面直接打开了,而不是提示下载,这样的话如果txt文件的内容非常多的话肯定是不行的,可能就会导致浏览器挂掉,客户机器死机的问题
现整理了个解决办法,代码如下:
1.下载页面
open(action执行页面,'iframeName','');
2.action执行页面
<a id="tempB" style="display:none" href="#" onclick=""> </a>
<iframe width=0 height=0 id="hideIframe" name="hideIframe"></iframe>
<script>
var n=0;
function go(url){
n==0?new function()
{
frames("hideIframe").location=url,n=1
}:null;
document.all("hideIframe").readyState!="complete"?setTimeout(go,10):so();
function so()
{
frames("hideIframe").document.execCommand("SaveAs"),n=0
};
}
var tempB = document.getElementById("tempB");
<%
if(path.toLowerCase().indexOf(".txt")>=0){
%>
tempB.attachEvent('onclick',function(){go('<%=request.getContextPath()+"/tempfile/1.txt">');});
<%
}else{
%>
tempB.attachEvent('onclick',function(){open('<%=request.getContextPath()+"/tempfile/1.xls">','','');});
<%
}
%>
tempB.click();
</script>
websphere部署war应用失败正常原因是web.xml的节点定义循序问题,或者一些空格,字符原因造成的
可能先定义完所有的servlet后再定义所有的servlet mapping就没问题了
那个转向后的页面已经有用gb2312的编码了
可能原因是在java类里面调用了((HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getWriter().write("");
然后再转向某个页面,这样可能导致编码格式冲突,导致乱码
可以先给resonse设置下编码格式,然后在write
HttpServletResponse httpServletResponse = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
httpServletResponse.setContentType("text/html; charset=gb2312");
httpServletResponse.setCharacterEncoding("gb2312");
httpServletResponse.getWriter().write("");
这样应该就可以解决了
C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\config\cells\app-bi2Node01Cell\applications\appname.ear\deployments\appname\appname.war\WEB-INF\web.xml 该目录下的web.xml的修改才是有效
应用程序发布的目录下的那个web.xml添加的servlet配置是无效的
可能原因:
1: form表单中的控件没有定义name属性
2: form表单中的控件被设置成disabled
3: form表单的enctype="multipart/form-data"是一种用于上传文件的表单
|
解决方法:
对于第三种情况我们直接request.getParameter来取参数值是取不到的
我们可以借用apache的上传组件来解决
用到jar包commons-fileupload-1.1.1.jar
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import
org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
*获取各种类型表单的表单参数
*@paramrequest HttpServletRequest请求对像
* @paramparamName 参数名
*@return
*@throwsFileUploadException
*/
publicstatic String
getParameterValue(HttpServletRequest request,String paramName) throws
FileUploadException{
boolean
isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart==true){
FileItemFactory
factory = new DiskFileItemFactory();
ServletFileUpload
upload = new ServletFileUpload(factory);
List
fileItemList = upload.parseRequest(request);
if(fileItemList!=null){
for(Iterator itr=fileItemList.iterator();itr.hasNext();){
FileItem fileItem = (FileItem)itr.next();
if(fileItem.getFieldName().equalsIgnoreCase(paramName)){
return new
String(fileItem.getString().getBytes("ISO8859-1"))//中文转码
}
}
}
}else{
return new String(request.getParameter(paramName).getBytes("ISO8859-1"))//中文转码
}
return"";
}
|
1.定义一个标签要用到两个java类,这个跟jsp的自定义标签有点不一样
第一个类继承UIComponentTag, 用于定义标签的属性和设置标签的所有属性值到控件的map属性attributes或valueBinding中
第二个类继承UIInput或者UIOutput,用于渲染标签的内容,真正打印标签内容的地方就在这里
2.这两个类是怎么联系的
我们需要像定义jsf的bean的影射文件一样,在faces-config.xml或者自己定义的xml文件里面定义第二个类
如:
<faces-config>
<!--分页标签-->
<component>
<component-type>pageTag</component-type>
<component-class>com.jsf.PageComponent</component-class>
</component>
</faces-config>
然后第一个类要实现父类的一个方法 public String getComponentType();从这里返回一个字符串pageTag,这样就跟第二个类联系起来了
3.标签属性的定义
标签属性的定义一般都是可转化为字符串的类型的,除非你还是用<%=rowList%>这种jsp赋值的方式
别以为你定义的一个List类型的属性可以用jsf的EL表达式可以直接赋值进来,EL表达式传进来以后属性接收的就是这一串EL表达式
所以就是说你的属性就是要字符串类型的
4.那么jsf自定义标签是怎么接收EL表达式绑定的列表的
先通过父类的isValueReference(属性值),来判断该属性的值是否是一个EL的表达式
如果是则通过获取绑定值得方式把真正的属性的值设置到标签父类的valueBinding对像中
否则直接把属性的值添加到标签父类的attributes对像中
if (isValueReference(属性值)) {
javax.faces.el.ValueBinding vb = Util.getValueBinding(value.toString());
component.setValueBinding(name, vb); //component就是标签对像,name就是标签的属性名称
} else {
component.getAttributes().put(name, 属性值);
}
这就是个设置属性值的过程,可以在第1点说的第一个类里面的protected void setProperties(UIComponent component)方法
5.现在知道标签属性值的作用了吗
是的标签属性值只不过是起个作用而已,而不是我们真正所要的值
也就是说我们是不能从这些属性中直接取值的
6.那么我们怎么取属性的真正的值呢
可以先从第4点说的标签父类的attributes对像中取值
如果取不到值那就到标签父类的valueBinding对像中取值
说白了就是,通过第4步我们属性的真正的值不是放在attributes就是在valueBinding中
Object obj = component.getAttributes().get(name); //component就是标签对像,name就是标签的属性名称
if (obj == null) {
ValueBinding vb = component.getValueBinding(name);
if (vb != null) {
return vb.getValue(context);
} else {
return null;
}
}
这个过程就是取属性值的过程,在第1点说的第二个类里面进行
7.现在属性值也可以取到了,那么我们要怎么打印标签的内容呢
我们可以在第二个类的encodeBegin或者encodeEnd中进行
public void encodeBegin(FacesContext context) throws IOException
public void encodeEnd(FacesContext context) throws IOException
取属性值的过程也可以在这里进行,取完值后就是把值组装到标签内容的相应位置中就完了
基本上就是这几点
在本地tomcat5中这样没问题
request.getRealPath("/")+"report/config/configFile/"+priv_id+".xml"
但是发布到websphere6后就出问题了
要改成
request.getRealPath("/")+"/report/config/configFile/"+priv_id+".xml"
就是report前要加个"/" 斜杠,加了后tomcat5下也是正确的
1.jdk环境问题
jdk环境要改为ibm 的jdk 5.0, 不然连接不上数据库, 数据库连接池的连接失败,c3p0连接池的连接失败,目前还是默认的方式采用应用服务器的连接池,像tomcat就采用tomcat配置的连接池
eclipse 的开发时用的jre如果修改为ibm的以后,有可能会导致编译不了,这要修改编辑器java类型的编码为gb2312就可以了,genaral->content type –java file
2. 程序中编写sql时的用户模式问题
用户模式要用公共常量,以便修改
不同用户模式之间的表的访问通过授权来解决
3. db2数据库的函数问题
程序中的添加和修改时间的地方的日期函数都要修改成
Date(“2007-01-01”)就是字符串中间有带中杠的
日期转字符串要把原先的to_char改成char(int(2007-01-01))
Kpi的消息串在配置中在取权限priv_id的字符串要加上char(int(priv_id)),如果直接char(priv_id)会多出一个点号
4. oracle树形结构的查询移植到db2存在问题
菜单查询中,有存在层次level的没实现,目前我先通过自己写的函数实现,但存在问题跟没有层次的实现方式一样存在问题
因为通过in的方式,in的存在字段是有限的到时候数据量变多了,sql就会执行失败,可以考虑临时表来解决
5. 序列表seq的长度问题
所有的序列表的序列长度db2是有限制的,好像不能大于8位,这样序列的字段都要做修改,而且不能重复,要进一步确认修改
7. 系统权限移植问题
地区编码的字段从数值型改为字符串类型,很辛苦,建议以后程序的bean的属性都用字符串来定义,避免程序移植的类型修改的问题
8. erwin数据模型问题
数据模型中的部分表没有及时更新,跟开发时用的表有出入,以后数据模型要及时更新
9. 建表的sql语句问题
建表的sql中
number(12) 这样的都要改成decimal(12,0)
varchar2都要改成varchar
有时候我们在表单提交后却获取不到控件的值
可能原因:
1. 控件少了name属性
2.控件被设置成disabled
后台数据处理完成的时候设置一个处理完成的session标志
前台通过发送ajax请求设置成功标志的session的页面,如果session的成功标志为true则数据处理完成,关闭正在处理的进度条图片,否则继续发送ajax请求,显示正在处理的进度条图片,当然也可以通过后台返回数据处理完成的百分比,来制作精确的进度条
当我们在做动态生成checkbox和动态设置checkbox的checked属性的时候要注意
只有checkbox在页面生成以后设置checkbox的checked属性才有效,否则是无效的
也就是说不要在create checkbox后就设置checked属性,要等到该checkbox已经append到页面中了在来设置checked属性这样才可以
1) 使用response.sendredirect重定向是没办法通过request.setAttribute来传递对象到另外一个页面的
但我们可以通过转发的方式来实现request.getRequestDispatcher("test2.jsp").forward(request,response)
这也是struts默认的页面跳转方式,这就是为什么我们可以在action里面request.setAttribute然后在页面里request.getAttribute
2) 使用response.sendredirect重定向要记得在后面加上return不然后面的语句还是会继续往下执行的,还有就是response.sendredirect之前最好不要有任何的输出语句包括html不然可能会重定向失败
最近我还遇到一个比较奇怪的问题就是response.sendredirect失败,因为我的端口是通过交换机来转换的所以可能就是在这里重定向不过去了,所以建议以后大家都使用request.getRequestDispatcher("test2.jsp").forward(request,response)这种方式就不会错了,当然也可以用jsp标签的forward