【项目需求】
一个页面,通过抓取数据,获取需要处理的数据的列表。对此列表数据进行单条或批量操作后,将数据存入到另一个表中,存入前先判断是否存在该条记录,存在则更新,不存在则插入。
【开发环境】
MyEclipse、Oracle
【开发问题】
在将记录存入到数据库时,遇到了一个问题,中文乱码~~~乱码真是一个老朋友,当初在.net开发用mysql数据库,也遇到了乱码的问题。找了很久的解决方案,最后需要修改的是数据库的字符集格式设置。下面就看看这次java开发中是如何解决乱码问题的。
【开发过程】
方案一:用ajax的post方式,将js拼接好的json串作为参数写到url中。
拼接的json:
json+="{" + "\"receiveno\":" + "\"" + receiveno +"\"," + "\"adrcheckway\":" + "\"" + adrcheckway +"\"," + "\"addresscheckinfo\":" + "\"" + name_checkadr + "\"," + "\"telephone\":" + "\"" + mobile +"\"," + "\"companyname\":" + "\"" + companyname + "\"," + "\"companyaddress\":" + "\"" + companyaddress + "\"," + "\"companyphone\":" + "\"" + companyphone + "\"," + "\"adr_checkname\":" + "\"" + adr_checkname + "\"," + "\"companyquhao\":" + "\"" + companyquhao + "\"," + "\"adrPedcheckway\":" + "\"" + adrPedcheckway + "\"," +"\"adrcheckmethod\":" + "\"" + adrcheckmethod + "\"," +"\"adrconfirm\":" + "\"" + adrconfirm + "\"," + "\"checkwaytel\":" + "\"" + checkwaytel + "\"," + "\"telcheckinfo\":" + "\"" + telcheckinfo + "\"," +"\"checkwaytelped\":" + "\"" + checkwaytelped + "\"," + "\"telcheckinfoped\":" + "\"" + telcheckinfoped + "\"," + "\"telcheckmethod\":" + "\"" + telcheckmethod + "\"," + "\"telconfirm\":" + "\"" + telconfirm + "\"," + "\"fname\":" + "\"" + fname + "\"," + "\"frelation\":" + "\"" + frelation + "\"," + "\"fmobile\":" + "\"" + fmobile + "\"," + "\"address\":" + "\"" + address + "\"," + "\"adrquhao\":" + "\"" + adrquhao + "\"," + "\"adrphone\":" + "\"" + adrphone + "\"," + "\"lname\":" + "\"" + lname + "\"," + "\"lrelation\":" + "\"" + lrelation + "\"," + "\"lmobile\":" + "\"" + lmobile + "\"," + "\"mail\":" + "\"" + mail + "\"," + "\"postadr\":" + "\"" + postadr + "\"," + "\"postbill\":" + "\"" + postbill + "\"," + "\"companyfenji\":" + "\"" + companyfenji + "\"},";
json="[" + json.substring(0,json.length-1) + "]";
ajax:
$.ajax({
url: '/WebCheckAction.do?action=save&jsonresult=' + json,
type: 'post',
success: function(result) {
alert("保存成功!");
},
error: function(){
alert("保存失败!");
}
});
此方案是第一个开发思路,结果我在后台打印json串的时候,中文就成了乱码,存到数据库的也成了乱码。
后台代码:
public ActionForward save(ActionMapping mapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Throwable {
HttpSession session = request.getSession(false);
WebUtil webUtil = new WebUtil(response);
if (session.getAttribute("OperId") == null) {
webUtil.htmlAlert("无法确定您的身份,您可能已经超时,请尝试重新登陆!");
return null;
}
WebCheckForm webcheckform = (WebCheckForm) actionForm;
WebCheckBean webcheckbean = new WebCheckBean();
//获取js中url传过来的参数;
String json=request.getParameter("jsonresult");
//输出json串,中文已经变成乱码;
System.out.print(json);
webcheckform.setJsonresult(json);
//插入
webcheckbean.insert(webcheckform);
return mapping.findForward("save");
}
方案二:直接提交表单。
既然用ajax会有中文乱码的问题,那我就换个方案,该用表单提交,将json串显示在一个隐藏的表单中,然后作为参数直接提交。
js:
//将拼接好的json赋值到表单中的隐藏文本框中
document.getElementById("jsonresult").value=json;
//直接提交表单
document.all.webcheckform.action = "/WebCheckAction.do?action=save&jsonresult="+document.all.jsonresult.value;
document.all.webcheckform.submit();
这样的数据传到后台,中文不再有乱码问题。但用户体验度太差,我只是保存,不提交,它会整个页面刷新,而且没有相应的提示,那些我没有选择保存的数据也不再显示,达不到我需要的效果。
方案三:仍使用ajax,解决url传值乱码问题。
既然表单提交的方式不行,那我只有回到ajax,去解决乱码问题。
从网上找了很多相关的方案,解决问题的思路都是一致的:
JS编码,JAVA后台解码。
改写ajax:
$.ajax({
//在url传值时,对json进行二次编码,然后在后台进行解码
url: '/WebCheckAction.do?action=save&jsonresult=' + encodeURI(encodeURI(json)),
type: 'post',
success: function(result) {
alert("保存成功!");
},
error: function(){
alert("保存失败!");
}
});
后台解码:
public ActionForward save(ActionMapping mapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Throwable {
HttpSession session = request.getSession(false);
WebUtil webUtil = new WebUtil(response);
if (session.getAttribute("OperId") == null) {
webUtil.htmlAlert("无法确定您的身份,您可能已经超时,请尝试重新登陆!");
return null;
}
WebCheckForm webcheckform = (WebCheckForm) actionForm;
WebCheckBean webcheckbean = new WebCheckBean();
//获取js中url传过来的参数;
String json=request.getParameter("jsonresult");
//利用java中URLDecoder对json进行解码
json=java.net.URLDecoder.decode(json,"UTF-8");
webcheckform.setJsonresult(json);
System.out.print(json);
webcheckbean.insert(webcheckform);
return mapping.findForward("save");
}
至此,对于url中参数的中文乱码问题就解决了。但是问题并没有结束,我在执行批量保存的时候,总是保存失败。怎么回事?后来经过多次测试,发现问题的源头:
如果是保存四五条数据没问题,但如果保存的记录数多了,就保存失败。
很奇怪,这又是什么问题?那个上午吃饭前也没有解决,后来在吃饭的时候,突然想到,是不是因为我的json串太长了,url有长度限制。吃完饭回来,就查了一下,url果真有长度限制问题。所以,问题的解决方案还需要继续下去。
方案四:继续改写ajax,将参数从url中去掉,换成data写法。
var jsonresult="";
//现将json进行二次编码
jsonresult=encodeURI(encodeURI(json));
$.ajax({
url: '/WebCheckAction.do?action=save',
type: 'post',
//将编码后的json作为参数
data: {"jsonresult":jsonresult},
success: function(result) {
alert("保存成功!");
},
error: function(){
alert("保存失败!");
}
});
改写了ajax后,后台的解码又出现问题了。通过输出的json发现,json串没有完全解码。
既然是没有完全解码,我就想要不然就在js中进行一次编码,再到后台进行解码。
js:
var jsonresult="";
//现将json进行一次编码
jsonresult=encodeURI(json);
$.ajax({
url: '/WebCheckAction.do?action=save',
type: 'post',
//将编码后的json作为参数
data: {"jsonresult":jsonresult},
success: function(result) {
alert("保存成功!");
},
error: function(){
alert("保存失败!");
}
});
后台解码也需要换个写法:
public ActionForward save(ActionMapping mapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Throwable {
HttpSession session = request.getSession(false);
WebUtil webUtil = new WebUtil(response);
if (session.getAttribute("OperId") == null) {
webUtil.htmlAlert("无法确定您的身份,您可能已经超时,请尝试重新登陆!");
return null;
}
WebCheckForm webcheckform = (WebCheckForm) actionForm;
WebCheckBean webcheckbean = new WebCheckBean();
//获取经过一次编码后的json串
String json=request.getParameter("jsonresult");
//将json用iso-8859-1编码回去,再用utf-8解码回来
json=new String (json.getBytes("iso-8859-1"),"utf-8");
//解码
json=java.net.URLDecoder.decode(json,"UTF-8");
webcheckform.setJsonresult(json);
System.out.print(json);
webcheckbean.insert(webcheckform);
return mapping.findForward("save");
}
至此,这个乱码问题才算是真正解决。
【开发总结】
经过这一次的开发过程,让我又积累到了一个解决乱码的方式:JS编码,JAVA解码。此方案是从自己的开发实战中获得,用的是post方式,如果用get方式,情况可能还会不太一样。
这一过程,遇到的问题也是挺多的,但每遇到一个问题,关键是去寻找解决问题的方案、思路,有着清晰的开发流程,有着明确的开发目标,即使遇到的问题再多,也都会解决的。