您的位置:首页 > 运维架构 > Tomcat

【技术贴】servlet传参|前台传参含中文符号等 tomcat乱码 java后台接收乱码终极解决方

2013-03-08 18:08 555 查看
1.前台传参,一定要编码,否则中文传不出来~~tomcat乱码此篇只适合于tomcat中文传参乱码,websphere6.1中文传参乱码请移步http://hi.baidu.com/ae6623/item/27c43f57e913a0cad2e10c46

前台如果用js进行了编码,后台用jsp或者servlet进行解码的时候就有可能乱码,如下,是我遇到的一个问题。

我的前台js里面写:

var descMsg = encodeURIComponent($("#descMsg").val()); parm = "pdfHeadsDefine?docNo=" + docNo +"&companyCode=" + companyCode +"&descMsg=" +descMsg;location.href = (parm);

后台jsp如果解码这样写:

String descMsg = new String(req.getParameter("descMsg").getBytes("ISO8859-1"), "UTF-8");
这样就解决了乱码。。

然后下面的是另一些情况。

Enumeration em = req.getParameterNames(); while (em != null && em.hasMoreElements()) { String paraName = (String) em.nextElement(); String paraValue = req.getParameter(paraName); queryString += "&" + paraName + "=" + URLEncoder.encode(paraValue, "utf-8");//编码 } if (queryString.endsWith("&")) { queryString = queryString.substring(0, queryString.length() - 1); }

2.后台接收的时候,不用再次用什么decode去解码,因为getParameter的时候,servlet会自动解码一下,而我们需要做的就是空值处理(你的业务不需要这一步可以不做),和重新转码:

// 接收公司号 String companyCode = req.getParameter("companyCode"); // 接收目标公司号 String qtyCompany = req.getParameter("qty_company"); // 接收查询sql条件,不做trim()处理,防止前台可能传入带空格的查询条件 String condition = req.getParameter("con"); // 暂时未启用 String spName = req.getParameter("sp"); spName = spName == null ? "" : spName; String spParameters = req.getParameter("sp_args"); spParameters = spParameters == null ? "" : spParameters.trim(); // 接收sheetName,导出excel必备参数 String sheetName = req.getParameter("sheet_name"); // 接收fileName String fileName = req.getParameter("fileName"); // 接收最大值 String maxNumber = req.getParameter("maxNumber"); // 转码(字符集) companyCode = toDecode("companyCode", companyCode); qtyCompany = toDecode("qtyCompany", qtyCompany); condition = toDecode("condition", condition); sheetName = toDecode("sheetName", sheetName); maxNumber = toDecode("maxNumber", maxNumber); fileName = toDecode("fileName", fileName); // 处理文件名 fileName = "".equals(fileName) ? getReportNo(req) + ".xls" : fileName; // 对 sheetName做处理,非空否则报错. sheetName = "".equals(sheetName) ? fileName : sheetName;

转码方法:

/** * * toDecode:(转码). <br/> * * @param param * @return String * @since JDK 1.5 */ private String toDecode(String name, String param) { System.out.println(name + " 转码前的值为:" + param); param = param == null ? "" : param.trim(); try { param = new String(param.getBytes("ISO8859_1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println(name + " 转码后的值为:" + param); return param.trim(); }

此时你的所有中文参数都会变成正规的汉字.

3.然后还有最后一步,就是下载文件的时候,记得修改报文信息.

//在线预览 resp.setHeader("Content-Disposition", "inline;filename=" + new String((reportName).getBytes("gb2312"), "ISO8859_1")); //直接下载resp.setHeader("Content-Disposition", "attachment;filename=" + new String((reportName).getBytes("gb2312"), "ISO8859_1"));
// 判断是在线阅读还是下载保存

if (report.isReadOnline()) {

// 在线阅读

// resp.setHeader("Content-Disposition", "inline;filename=" + reportName);

// resp.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(URLEncoder.encode(reportName, "utf-8"),"utf-8"));

// resp.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(reportName, "utf-8"));

resp.setHeader("Content-Disposition", "inline;filename=" + new String((reportName).getBytes("gb2312"), "ISO8859_1"));

} else {

// 下载保存

// resp.setHeader("Content-Disposition", "attachment;filename=" + reportName);

// resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(URLEncoder.encode(reportName, "utf-8"),"utf-8"));

// resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(reportName, "utf-8"));

resp.setHeader("Content-Disposition", "attachment;filename=" + new String((reportName).getBytes("gb2312"), "ISO8859_1"));

}

这个最后一步简直就是杀手锏!!!!! 多次都是这段代码救我于水深火热之中,久久感激不尽!!

总结:

这个故事告诉我们,前台发送中文参数,一定要记得编码,因为 浏览器发送url请求的时候不识别的中文参数,比如说,你传值,name = &pass我哈 ,你说你怎么办,传出去,指不定后台就以为name是空呢,而且多了一个pass参数,因为pass前边有&符号,明显的参数嘛,所以要编码.

后台解码,我一开始就认为百度是权威的,既然编码了,为毛不解码,我就尝试解码,但是越解越不对劲啊,更乱了,那么好吧,百度上说什么前台二次编码,后台一次解码,因为getParameter会自动解码一次,刚好2次抵消,我次奥,我信了,直接前台二次编码,后台解码,你妹啊,更乱啊!!!

绝知此事要躬行,不敢私藏于单机,遂2013年3月8日18:07:47上传到百度博客,网友共乘凉.

ps 忘记说了,对于

param = new String(param.getBytes("ISO8859_1"), "utf-8");
这里的"ISO8859_1"是可以在tomcat的C:\tomcat7\conf\server.xml里面自己设置tomcat的默认编码,设置了之后,你就把"ISO8859_1"换成你设置的GBK啊,或者UTF-8,比如我把设置成了GBK,就可以写

param = new String(param.getBytes("GBK"), "utf-8");<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK" useBodyEncodingForURI="true" />总之,各种情况不一样,大家自己分析吧,多一条路子是一条路子~~祝你转码好运~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: