java中以post方式提交,中文编码&解码问题

    【项目需求】
    一个页面,通过抓取数据,获取需要处理的数据的列表。对此列表数据进行单条或批量操作后,将数据存入到另一个表中,存入前先判断是否存在该条记录,存在则更新,不存在则插入。
    【开发环境】
    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方式,情况可能还会不太一样。
        这一过程,遇到的问题也是挺多的,但每遇到一个问题,关键是去寻找解决问题的方案、思路,有着清晰的开发流程,有着明确的开发目标,即使遇到的问题再多,也都会解决的。

你可能感兴趣的:(【项目学习】,#,GDZX)