EXT combobox控件异步提交到后台中文乱码解决方案

    序:所有文件都是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格式。就这样,困扰我多日的问题也就随之解决,希望对于同样碰到此问题的同学们起到帮助。

你可能感兴趣的:(java,Ajax,ext,中文乱码,combobox)