序:所有文件都是GBK编码,JSP定义的是GBK编码,EXT文件也另存为了GBK编码。
项目里用ext的combobox控件做了一个动态下拉菜单,因为数据量可大可小,所以没有预先将数据加载到前台jsp,而是实时查询后台所有符合条件的数据。对于简拼和全拼的查询支持较好,但是输入中文却一直没法得到正确的搜索结果,debug后台代码,发现从前台传过来的数据是乱码。
后来在网上搜了很久,有很多人说把所有的编码都改成UTF-8就成(EXT默认是UTF-8),但这对于一个已经成熟应用的项目来说显然不实际。也有说在EXT文件中强制将POST编码修改为GBK的,经试验,此方法不可行。很多同学也说需要在传输前对url进行encodeuri,不过对于combobox在异步提交时一直没找到在那边进行encode。当然,ITEYE上也有同学说如果项目非要GBK,那这和EXT默认UTF-8编码就成了不可调和的矛盾,一下就被打击了,遂放弃好久没去理它。
不过想想这肯定有解决的办法,翻API时看到了beforquery,试了一下,原来可以在这个事件里对传输的query字符进行编码,后台java代码进行UTF解码。
附代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css"/>
<script type="text/javascript" src="../extjs/ext-base.js"></script>
<script type="text/javascript" src="../extjs/ext-all.js"></script>
<script type="text/javascript" src="../extjs/ext-lang-zh_CN.js"></script>
<HTML>
<HEAD>
<title>title</title>
<script type="text/javascript">
Ext.onReady(function () {
var ds = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '/spirit.do?method=jsonEmployee'
}),
reader: new Ext.data.JsonReader({
root: 'employees',
totalProperty: 'totalCount',
id: 'employeeId'
}, [
{
name: 'employeeId',
mapping: 'employeeId'
},
{
name: 'employeeName',
mapping: 'employeeName'
}
])
});
var resultTpl = new Ext.XTemplate(
'<tpl for="."><div class="search-item" >',
'<span style="width:225;padding-left:20px;">{employeeName}</span>',
'</div></tpl>'
);
function addSearch(t) {
var search = new Ext.form.ComboBox({
store: ds,
displayField: 'employeeName',
valueField: 'employeeName',
loadingText: '正在查找...',
emptyText: '请输入简拼或全拼',
minChars:1,
width: 180,
pageSize: 20,
listWidth:300,
hideTrigger:true,
tpl: resultTpl,
lazyInit: true,
lazyRender: true,
focusClass: '',
itemSelector: 'div.search-item',
listeners: {
'beforequery': function (e) {
var combo = e.combo;
if (!e.forceAll) {
var input = e.query;
//input:管
e.query = encodeURI(input);
//before:%E7%AE%A1
//后台java代码:String query = URLDecoder.decode(StringTool.safeToString(_form.getQuery(), ""), "UTF-8");
//after:管
combo.expand();
}
}
}
});
search.applyToMarkup(t);
t.search = search;
}
function txtOnFocus(evt, t, o) {
var _t = Ext.Element.get(t.id);
var n = _t.next();
if (n && n.hasClass('spirit-append')) {
n.dom.innerText = '';
}
}
function txtOnClick(evt, t, o) {
ds.load({params: {start: 0, limit: 20}});
}
var ss = Ext.select('.cust-employee-spirit');
for (var i = 0; i < ss.getCount(); i++) {
var el = ss.item(i);
el.addListener("focus", txtOnFocus);
el.addListener("click", txtOnClick);
addSearch(el.dom);
}
});
</script>
</HEAD>
<body>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="100px" nowrap>
用户姓名:
</td>
<td width="200px" nowrap>
<div class="employee-spirit-container-1">
<input type="hidden" name="employeeId" value="0">
<input type="text" name="employeeName" value="" class="inputbox cust-employee-spirit">
</div>
</td>
</tr>
</table>
</body>
</HTML>
关键就在于这一段:
'beforequery': function (e) {
var combo = e.combo;
if (!e.forceAll) {
var input = e.query;
//input:管
e.query = encodeURI(input);
//before:%E7%AE%A1
//后台java代码:String query = URLDecoder.decode(StringTool.safeToString(_form.getQuery(), ""), "UTF-8");
//after:管
combo.expand();
}
}
可以从代码注释中看出,我在输入框中传递的文本是“管”,encode之后转为了“%E7%AE%A1”,在后台需要再次将它转回UTF-8格式。就这样,困扰我多日的问题也就随之解决,希望对于同样碰到此问题的同学们起到帮助。