近期我遇到了一个问题,就是将在windows下运行正常的Java站点部署到linux下运行后中文请求参数解析乱码了。方法是我在客户端对要请求的中文参数进行两重encodeURIComponent()编码,后台直接调用request.getParameter()方法获取参数,并且对于Get和Post采用相同的方式处理。今天无意中尝试了一下如下的方法,发现不会出现这个问题了。方法如下:
首先,要明白GET请求和POST请求的机制是不一样的,所以编码机制也就不同。通过GET方式提交的参数在客户端必须显式调用编码函数进行编码,而通过POST方式提交参数时只要设置一下整体的编码方式即可,不需要单独对参数进行编码。客户端JSP页面的代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
var _blIsIE=true;
try{
new ActiveXObject("MicroSoft.XMLHTTP");
}catch(err){
_blIsIE=false;
}
function testGet(){
var xmlHttp=null;
if(_blIsIE==true)
xmlHttp = new ActiveXObject("MicroSoft.XMLHTTP");
else if(window.XMLHttpRequest)
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET","test?content="+encodeURIComponent(document.getElementById("txtContent").value)+"&t="+Math.random(),false);
xmlHttp.send(null);
document.getElementById("divResult").innerHTML = xmlHttp.responseText;
}
function testPost(){
var xmlHttp=null;
if(_blIsIE==true)
xmlHttp = new ActiveXObject("MicroSoft.XMLHTTP");
else if(window.XMLHttpRequest)
xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST","test?t="+Math.random(), false);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");//注意这里将POST的头部声明为了UTF-8编码
xmlHttp.send("content="+encodeURIComponent(document.getElementById("txtContent").value));
document.getElementById("divResult").innerHTML = xmlHttp.responseText;
}
</script>
</head>
<body>
<textarea id="txtContent" cols="40" rows="15"></textarea><br/><input type="button" value="GET测试" οnclick="testGet()"/> <input type="button" value="POST测试" οnclick="testPost()"/>
<div id="divResult"></div>
</body>
</html>
其次,服务端不能对GET请求和POST请求一概而论。当客户端设置为UTF-8后,服务端的POST方法就无需再解码了。服务端servlet的代码如下:
package com.smapp.dataexchange.service;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class test
*/
@WebServlet("/test")
public class test extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public test() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String strContent = request.getParameter("content");
strContent = new String(strContent.getBytes("iso-8859-1"),"UTF-8");<span style="white-space:pre"> </span>//可以看到只有GET请求才需要进行转码
response.setContentType("text/text");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(strContent);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String strContent = request.getParameter("content");
response.setContentType("text/text");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(strContent);
}
}
好了,运行jsp页面后测试提交中文参数时,无论通过GET还是POST方式都可以正确解析了。