欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

EXT combobox控件异步提交到后台中文乱码解决方案 博客分类: 工作总结 extjavaajaxcombobox中文乱码 

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