weixin_42355130
2009-12-28 13:43 阅读 308
已采纳

老问题,Strust2 + Ajax中文乱码

在下想完成这样一个简单的功能:
在页面上选择一个带有中文字符的下拉框中的值,引起级联变化。
但是第一个下拉框中的值传给Action后一直是乱码,恳请各位解决。下面贴出页面代码:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">


Insert title here




label="地区"
list="@xxx.xxx.XClass@XX_LIST"
name="s_district" emptyOption="true"
onchange="buildSelects(this.value,'company');" />
<s:select id="company" label="单位" list="#{'':'--请选择--'}"
    name="s_company" />

/s:form

以下是js代码:
//全局变量定义
var searchReq = createAjaxObj();
var selectUpdateId;// 要变动的Select ID
var arrayIds;// 联动select ID

function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("您的浏览器不支持");
}
}
}

function createAjaxObj() {
var httprequest = false;
if (window.XMLHttpRequest) { // if Mozilla, Safari etc
httprequest = new XMLHttpRequest();
if (httprequest.overrideMimeType) {
httprequest.overrideMimeType("text/xml");
}
} else {
if (window.ActiveXObject) { // if IE
try {
httprequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httprequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
}
}
}
}
return httprequest;
}

// Starts the AJAX request.
function buildSelects(propValue, subSelectId) {
// alert("buildSelects");
delSubInfos(subSelectId);
selectUpdateId = subSelectId;
if (searchReq.readyState == 4 || searchReq.readyState == 0) {
// var str = escape(document.getElementById("txtSearch").value);
alert(propValue);
searchReq.open("GET", "select.action?search=" + propValue, true);
searchReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
searchReq.onreadystatechange = handleSearchSuggest;
searchReq.send(null);
}
}

// Called when the AJAX response is returned.
function handleSearchSuggest() {
if (searchReq.readyState == 4) {
var str = searchReq.responseText;
alert(str + ", " + selectUpdateId);
var mes = str.split(",");
delSubInfos(selectUpdateId);
for (i = 0; i < mes.length; i++) {
var infos = mes[i].split("'");
document.getElementById(selectUpdateId).appendChild(createOption(infos[0], infos[1]));
}
}
}

// 创建Select Options
function createOption(propValue, textValue) {
var ops = document.createElement("option");
ops.setAttribute("value", propValue);
ops.appendChild(document.createTextNode(textValue));
return ops;
}

// 删除 Select Options
function clearOptions(selectNode) {
selectNode.length = 1;
// selectNode.childNodes[0].selected=true;
}

// initialization
function initAjax(argumentsMa) {
arrayIds = arguments;
alert(arrayIds[0] + "," + arrayIds[1]);
}

function delSubInfos(targetId) {
var canClear = false;
for (var i = 0; i < arrayIds.length; i++) {
//alert(arrayIds[i] + "," + targetId);
if (arrayIds[i] == targetId) {
canClear = true;
}
if (canClear) {
clearOptions(document.getElementById(arrayIds[i]));
}
}
}

先谢谢各位了
[b]问题补充:[/b]
To energyKey:
1、谢谢,但是。。。修改成POST以后仍然是乱码
2、在Action中有对request进行编码
以下是Action的代码

public class SelectAction extends ActionSupport {

private String search;

public String direct() throws IOException {

    HttpServletRequest request = ServletActionContext.getRequest();
    request.setCharacterEncoding("UTF-8");
    String s_search = URLDecoder.decode(search, "UTF-8");
    System.out.println(search + "," + s_search);

    // System.out.println("search=" + search);
    // 输出信息
    String news = null;
    try {
        news = ProvinceData.PROVINCE_DATA.get(search).toString();
    }
    catch (Exception e) {
        System.out.println(e.getMessage());
    }

    HttpServletResponse response = ServletActionContext.getResponse();
    // 设置编码
    response.setContentType("text/html;charset=UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    PrintWriter out = response.getWriter();
    out.print(news);
    // 关闭流
    out.close();
    return SUCCESS;
}

public String getSearch() {
    return search;
}

public void setSearch(String search) {
    this.search = search;
}

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    Ryankay Ryankay 2009-12-28 14:35

    HttpServletRequest request = ServletActionContext.getRequest();
    request.setCharacterEncoding("UTF-8");
    String s_search = URLDecoder.decode(search, "UTF-8");
    System.out.println(search + "," + s_search);

    这里你request.setCharacterEncoding("UTF-8");这句话有意义么?你set了这个肯定是要从request里拿search才有用的,但是你又用URLDecoder.decode(search, "UTF-8");这句话试图将一个中文的UTF-8代码解析为中文,要用这种也行,google百度都这样是吧,但前提是在你的ajax请求前先对汉字进行编码,但其实你这里根本没这个必要。

    searchReq.open("GET", "select.action?search=" + propValue, true);

    呵呵,看来你没有找到问题的根本。这里即使你改成了POST又有什么意义呢,你的search参数是写死在URL里的,凡是在URL直接指定的参数,都将以GET方式发送。所以最终你的中文还是被get发送了。

    你这里直接使用了最底层的ajax,没有用js框架,首先,很佩服你的个性。不过,我们可以参考一下JS框架他们是怎么做的,js框架里一般都有设置发送方式GET/POST,但POST一般通过IFRAME里的FORM来实现,POST只有通过FORM来实现,但放在页面内提交FORM肯定会造成页面刷新,所以放进了IFRAME。

    在来说说你的java代码,
    1.直接调用REQUEST,STRUTS2里你直接定义一个属性为search的字段,他将自动为你封装,这是最最基本的属性,要不然你用STRUTS2干嘛?看你的代码,直接改用SERVLET好了。
    2.直接调用RESPONSE,然后又return 一个SUCCESS.也许你是觉得所有的内容都是在news里,然后直接输出RESPONSE比较爽来着,这里有两种方式,一是使用FREEMARKER模板,这个模板文件,你只需写一行${news},后台把news set进request作用域里即可。非常简单。当然,也可以使用JSON,AJAX和JSON天生就是一对,而且,STRUTS2是有支持JSON的包的!你只需要继承这个包,然后在action里定义一个map,STRUTS2就会自动将MAP里的值翻译成JSON字符串。

    3.设置编码。STRUTS2中只需要一行代码,在struts.xml里这样设置一下即可。非常方便。用 这个不放心,没关系,SPRING也有一个ENCODING的FILTER,没用SPRING?也没关系,自己手动写一个filter,拦截所有请求。

    4.级联方面。为什么参数会是中文呢?改成ID-NAME的方式不是更好?建立一张省份ID-省份NAME的关系表。以NAME作为显示,ID作为参数,无论是编码、数据库检索效率都要比直接使用中文好。

    如果一定要提交中文的话,
    解决方式:
    要实现中文提交,就必须把参数放进form的input里,然后提交,要想页面不刷新,就必须放进iframe里。

    点赞 评论 复制链接分享
  • Ryankay Ryankay 2009-12-28 13:54

    1.searchReq.open("GET", "select.action?search=" + propValue, true);

    你的参数如果含有中文请用POST,GET不支持中文编码。

    2.是否处理过request的编码。request.setCharacterEndcoding("UTF-8");

    点赞 评论 复制链接分享