Friday, January 28, 2011

Tomcat URL 支持中文文件名

在tomcat的默认配置情况下,如果访问一个"中文.html"页面,服务器会抛出文件找不到的错误提示,这需要对tomcat的配置文件略作改动,为Connector设置URIEncoding的参数。
在server.xml文件中找到8080服务器配置的一段设置:

<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/>


加上 URIEncoding="UTF-8" 这句就可以识别中文文件名了,同时如果url中的参数值有中文,服务器端也可以正常解析对应的参数,否则服务器端Java程序中取到的参数是以ISO-8859-1编码的,有中文字符的参数值是乱码的,加了URIEncoding="UTF-8"之后,就可以正确获取到参数值了。
对于这个参数的说明,可以查看tomcat目录中的doc帮助文件,也可以从官网中找到此参数的解释。

References: 官方文档
Configure tomcat's uri encoding

IE throw null object exception when flash call javascript function

用open flash chart第一次正常载入一个图表到页面之后,当使用jQuery.fn.empty()方法移除此图表时,IE中会抛出一个错误,其他浏览器都是正常的,内容如下:


JScript - script block, line 1 character 124
'null' is null or not an object

通过IE8的debug工具可以看到出错时,javascript正在执行的代码如下:

try { document.getElementById("report-charts").SetReturnValue(__flash__toXML(ofc_resize([66,-96,66,-87])) ); } catch (e) { document.getElementById("report-charts").SetReturnValue("<undefined/>"); }

这个并不是页面中的javascript代码,应该是flash中调用外部javascript方法时,所使用的javascript代码,在IE8中断点调试,可以发现document.getElementById("report-charts")的结果为null,所以抛出了以上错误。
避过此问题的办法是在陊除已经载入的图表时,不调用jQuery.fn.empty()方法,而是直接使用jQuery.fn.html(''),将flash所在父元素的内容置空:

$('#report-charts').parent().html('');
// 如果使用$('#report-charts').parent().empty();在IE中则会报错
// ... 重新生成report-charts对象并载入新的flash图表
swfobject.embedSWF(ofc, "report-charts", "100%", "300", "9.0.0", "expressInstall.swf", {"get-data":"get_chart_0"});

Thursday, January 27, 2011

sqlite3 database disk image is malformed

sqlite3 报错提示: database disk image is malformed

看提示意思是指数据库的数据文件格式发生异常,所以数据查询和写入不正常,在网上google了一些文章,找到了一个解决方法。
一般来说,sqlite3的数据文件发生这个问题,想直接修复数据是行不通了,
在进入sqlite3后的命令行中,运行以下命令:
PRAGMA integrity_check
*** in database main ***
On tree page 120611 cell 0: 3 of 4 pages missing from overflow list starting at 120617
On tree page 120616 cell 0: 3 of 4 pages missing from overflow list starting at 120621
On tree page 3309 cell 0: 3 of 4 pages missing from over

假设原数据库名: abc.db

运行命令:
$> sqlite3 abc.db

.output "data.sql"
.dump
.quit

再建个新数据库 abcd.db
$> sqlite3 abcd.db

然后

.read "data.sql"
.quit

然后修复原来的数据库名和文件权限,应该就没事了。

References: sqlite3 database disk image malformed

Open Flash Chart IO ERROR Loading test data Error #2032

在IE6中使用open flash chart2加载图表的json数据时,第一次载入数据,图表渲染正常,第二次就会报一个错误,提示数据加载错误:


Open Flash Chart
IO ERROR
Loading test data
Error #2032

而在其他的浏览器,如IE8/firefox/chrome中都是正常的,在网上搜索了一些回答,其中有人提到说这是因为浏览器的缓存造成的问题,只要在用swfobject加载open-flash-chart.swf时,在url后面加上一个动态参数,让浏览器不要使用本地缓存:

swfobject.embedSWF("open-flash-chart.swf?t=" + (new Date()).getTime(), "charts-div-id", "100%", "300", "9.0.0", "expressInstall.swf", {"get-data":"get_chart_0"});


References: Open Flash Chart IO ERROR Loading test data Error #2032

Thursday, January 13, 2011

springmvc 中ajax提交发生乱码问题

这个问题目前只是在springmvc项目中碰到,在IE和Chrome中,当用jQuery.post()方法发起ajax请求时,Controller中收到的中文内容变成乱码了,而在firefox中用jQuery.post()进行ajax请求时是正常的。
在Controller中调用如下代码(项目为UTF-8编码):


// name 是post收到的字符串变量名
System.out.println(new String(name.getBytes(HTTP.ISO_8859_1), HTTP.UTF_8));

可以看到乱码恢复正常,说明IE和Chrome提交的ajax请求中的内容被编码成 ISO-8859-1 编码了。
而实际上,对于IE而已,所有的ajax请求都是以UTF-8方式发起的,通过以下方式设置ajax请求的编码为GBK实际是没有用的,服务器收到仍然是UTF-8编码的请求体:

xmlhttp.setRequestHeader( "Content-Type", "text/html;charset=GBK" );
// or
xmlhttp.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=GBK");

因此可以肯定是springmvc在收到POST请求后,将请求体的数据用 ISO-8859-1 编码来处理了,最后传到Controller中时变成了乱码,但是为何firefox中提交的却仍然是正确的呢?
在firebug中观察firefox中的ajax请求头,可以看到firebug中的提示:

Content-Type application/x-www-form-urlencoded; charset=UTF-8

而在IE中用http analysis工具看到的却是:

Content-Type application/x-www-form-urlencoded

google Chrome中与IE一样,ajax请求头中没有指明编码,所以Chrome和IE一样将发生乱码了。
查看jquery-1.4.4.js源码可以看到,jQuery中原来的 contentType设置为"application/x-www-form-urlencoded",IE和Chrome中的请求头显示是正确的,没有问题,反而是firefox将contentType中设置了编码。
从这个请求头分析来看,应该是springmvc没有得到请求的编码,而将其内容设置为ISO-8859-1了,因此发生了乱码的情况。

解决方法还是参考firefox的请求头,在contentType中指定编码,明确告诉服务器端,当前请求体的编码方式为UTF-8。

xmlhttp.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

如果使用jQuery发起ajax请求,javascript的代码改为如下方式发起ajax请求,而不是以$.post()和$.get()等快捷方法:

$.ajax({
url: url,
type: "POST",
dataType: "html",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data: data,
complete:function(data) {
}
});