基于spring+struts的前台框架,Struts2本身已经提供了ajax的封装.但是我们在项目开发中没有采用.现在发现需要将大量通过普通提交的内容都改为Ajax提交方式.为了对代码尽量少的修改,我们不得不自行实现解决方案.
原本为了解决中文提交的问题,已经提供了一个SetCharacterEncodingFilter过滤器.这个解决方案也是网上流行的方法.过滤器的写法也大同小异.
但是当进行ajax提交时,就出现了问题.无论怎么提交,后台得到的总是乱码内容.我分析,这可能是客户端,服务端以及页面,过滤器中都在处理代码转换的 问题,而且各自为政.因此过滤器可以解决客户端自动提交的中文问题,但是如果脚本提交时,客户端的某个部分没有参与编码传递的工作,这样就打乱了整个工作 程序.导致最终得到的乱码.所幸,无论怎么样的打论编码工序,ascII码是共通的低层格式.
针对这个问题,我参考了网上的一些方法,总结出了一套解决方案,就是将数据全部以ascII码传递.然后,到了后台,再统一转回UTF-8.在后台部分由拦截器来实现统一的内码转换.
ajaxform.js
原本为了解决中文提交的问题,已经提供了一个SetCharacterEncodingFilter过滤器.这个解决方案也是网上流行的方法.过滤器的写法也大同小异.
但是当进行ajax提交时,就出现了问题.无论怎么提交,后台得到的总是乱码内容.我分析,这可能是客户端,服务端以及页面,过滤器中都在处理代码转换的 问题,而且各自为政.因此过滤器可以解决客户端自动提交的中文问题,但是如果脚本提交时,客户端的某个部分没有参与编码传递的工作,这样就打乱了整个工作 程序.导致最终得到的乱码.所幸,无论怎么样的打论编码工序,ascII码是共通的低层格式.
针对这个问题,我参考了网上的一些方法,总结出了一套解决方案,就是将数据全部以ascII码传递.然后,到了后台,再统一转回UTF-8.在后台部分由拦截器来实现统一的内码转换.
![](https://p-blog.csdn.net/images/p_blog_csdn_net/mycsoft/423155/o_ajaxform%E6%B4%BB%E5%8A%A8%E5%9B%BE.jpg)
//------------------------------------------------------- //本脚本提供了将原始form提交改由ajax方式实现. //实现范例: // submitByAjax(form); // submitByAjax(form,function(){ // ...... // }); //------------------------------------------------------- /** * 通过ajax进行表单提交 */ function submitByAjax(form,callbackNam) { var url = form.action; var content = getFormQueryString(form); //alert("参数:"+content); if (form.method.toLowerCase()!="post") { url += ("?"+content); content = null; } if (callbackNam==null) { callbackNam = function(s){ document.open(); document.clear(); document.write(s); document.close(); }; } //提交 ajax_request(url,callbackNam,form.method,content); } //------------------------------------------------------- // Date : 2007/01/25 // Desc : Get all the from object // include type : hidden,text,select, checkbox,radio,file // none-include : button,submit,reset,image // Params : frmID: Form's ID or Name //------------------------------------------------------- function getFormQueryString( frmID ) { var i,queryString = "", and = ""; var item; // for each form's object var itemValue;// store each form object's value for( i=0;i<frmID.length;i++ ) { item = frmID[i];// get form's each object if ( item.name!='' ) { if ( item.type == 'select-one' ) { itemValue = item.options[item.selectedIndex].value; } else if ( item.type=='checkbox' || item.type=='radio') { itemValue = item.value; } else if ( item.type == 'button' || item.type == 'submit' || item.type == 'reset' || item.type == 'image') {// ignore this type continue; } else { itemValue = item.value; } itemValue = encodeURIComponent(itemValue); itemValue = encodeURIComponent(itemValue); //据说要2次 //itemValue = encodeURI(itemValue); queryString += and + item.name + '=' + itemValue; and ="&"; } if ( item.checked == false ) { continue; } } return queryString; } //ajax提交 function ajax_request(url, deal,method,content) { if (method == null) { method = "get"; } var http_request = null; if(window.ActiveXObject) { try { http_request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { http_request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } else if(window.XMLHttpRequest) { http_request = new XMLHttpRequest(); if (http_request.overrideMimeType) { http_request.overrideMimeType('text/xml'); } } if(!http_request) { return; } if(method.toLowerCase()=="post") { //alert("ajax xml"); http_request.open(method, url, false); //http_request.setRequestHeader('Content-Type','text/xml;charset=gbk'); http_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); } else{ http_request.open(method, url, false); } http_request.onreadystatechange = function() { if(4 == http_request.readyState) { if(200 == http_request.status) { deal(http_request.responseText); } else { alert(http_request.status); } } } http_request.setRequestHeader('If-Modified-Since','0'); http_request.send(content); }JSP页面中原本的提交改为:
<form οnsubmit="submitByAjax(document.forms[0]);">
......
</form>
后台拦截器:
package com.simlink.emr.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
/**
* Ajax form 拦截器.主要职责是将前台的中文解码.
* @author Ma Yichao
*/
public class AjaxFormInterceptor extends AbstractInterceptor {
private static Log log = LogFactory.getLog(AjaxFormInterceptor.class);
@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
HttpServletRequest req = ServletActionContext.getRequest();
HttpSession session = req.getSession();
for (Iterator it = req.getParameterMap().entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
Object value = entry.getValue();
if (log.isDebugEnabled()) {
log.debug("===========================");
log.debug("key=" + entry.getKey());
log.debug("old value=" + value);
}
if (value instanceof String) {
//entry.setValue(URLDecoder.decode((String) value, "utf-8"));
value = URLDecoder.decode((String) value, "utf-8");
}else if(value instanceof String[]){
//Struts中传递对象时,多用String[]而非String.
String[] values = (String[])value;
for (int i = 0; i < values.length; i++) {
String string = values[i];
values[i] = URLDecoder.decode((String)string, "utf-8");
}
}
entry.setValue(value);
if (log.isDebugEnabled()) {
log.debug("new value=" + entry.getValue());
log.debug("---------------------------");
}
}
return actionInvocation.invoke();
}
}
拦截器配置: <?xml version="1.0" encoding="gb2312"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="interceptor" extends="struts-default"> <interceptors> <interceptor name ="ajaxformInterceptor" class ="com.simlink.emr.interceptor.AjaxFormInterceptor"/> <interceptor-stack name="ajaxformStack"> <interceptor-ref name="ajaxformInterceptor" /> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> ...... </package> </struts>Struts Action配置:
<action name="updateXXX" class="xxxAction" method="updateXXX"> <interceptor-ref name="ajaxformStack"/> <result name="success" type="redirect"> ...... </result> </action>如此,就可以将普通提交的Form改为ajaxform. 不过我,总是想,应该有办法不需要在后台转换,在前台用ajax完全模拟普通提交.