`
eyesmore
  • 浏览: 376185 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

request.setCharacterEncoding 关于编码

阅读更多

request.setCharacterEncoding 关于编码

 

概述
从Servlet2.3开始,支持客户端内容协商。服务端内容协商,很早就有,服务端在返回的数据中通过Content-Type来指定返回的数据内容。在REST叫嚣的背景下,客户端也需要协商:例如通过PUT方法提交一段XML或JSON数据来更新服务端的一个对象。客户端可通过URL后缀名.xml或.json的方式来告诉服务端提交的数据类型;也可通过HTTP头的Content-Type来告之服务端提交的数据类型。

 

关于该问题的Blog

1 】给出了两个办法

http://forum.springsource.org/showthread.php?t=14063

Hi,
I am woking on a site that receives input in CJK .
This may be a naive  question:
I am using org.springframework.web.servlet.DispatcherServlet as my servlet and I need to set CharacterEnconding on the HttpServletRequest.
I looked into the source code and I relaized there is no code that calls setCharacterEncoding

I dig into the forum and found 2 solutions:

1. Use the CharacterEncodingFilter

2. Override DispatcherServlet.doService  as:
public class MyServlet extends DispatcherServlet {
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding( "UTF-8" );
super.doService( request , response ) ;
}
}

I tried to do #1 for it seems to be more desirable (cleaner) solution.
in web.xml I added:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFi lter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

But it doesn't seem to work.
Could someone tell me how to do that? Use CharacterEncodingFilter?
Thanks in advance.

 

【2】注意事项

http://www.junlu.com/msg/125726.html

With the 2.3 servet API, there is a new method:
 request.setCharacterEncoding(String encoding)
通过Content-Type告诉服务端当前请求编码:
This lets you tell the server a request's character encoding.
(例如HTTP头: Content-Type:    text/html; charset=UTF-8
Content-Type:application/x-www-form-urlencoded; charset=UTF-8)

It is critical that  setCharacterEncoding is called BEFORE any
request.getParameter is called (or getReader). Otherwise, you are at the
mercy of the appserver for what you get back on the getParameter call.

For example, if setCharacterEncoding is not called, you could get a null
value back on getParameter("foo").

 

 

解决该问题:客户端协商编码方式

private String negotiateCharacterEncoding(HttpServletRequest request,Map<String,String> outParam) {
		String clientEncoding = request.getCharacterEncoding();//HTTP标准:客户端声称的编码(但是目前大多数浏览器并未实施该标准)
		outParam.put("point","HTTP标准");
		//协商过程:
		//1. 通过HTTP标准指定客户端编码;(在HTTP头中设置:Content-Type	=[text/html; charset=UTF-8])
		//2. 通过自定义HTTP头(Client-Charset)指定客户端编码;
		//3. 通过自定义HTTP查询参数(Client-Charset)指定客户端编码(只针对HTTP-GET方法)。(以免动态script标签发起请求时设置不了HTTP头;编码数值都是英文字符,提取编码数值跟编码无关。)
		//4. 如果所有的协商都没有,那么服务端强制使用配置:defaultEncoding
		//5. 如果服务端没有配置defaultEncoding,那么使用容器默认的ISO-8...(如果上述指定的编码不被支持,那么依然使用容器默认的)
		if(clientEncoding==null || clientEncoding.trim().equals("")) {
			clientEncoding = request.getHeader("Client-Charset");
			outParam.put("point","自定义HTTP头");
			if(clientEncoding==null || clientEncoding.trim().equals("")) {
//				clientEncoding = request.getParameter("Client-Charset");//不能通过该方式提取Client-Charset参数
//request.setCharacterEncoding(encoding);发挥作用的前提是:调用setCharacterEncoding之前不能执行任何request.getParameter
				if("GET".equalsIgnoreCase(request.getMethod())) {
					String queryString = request.getQueryString();
					if(queryString!=null && !queryString.equals("")) {
						//定位参数[Client-Charset]的起始和终止位置
						int startIndex = queryString.indexOf("Client-Charset=");
						int endIndex = -1;
						if(startIndex!=-1) {
							startIndex = startIndex+"Client-Charset=".length();
							endIndex = queryString.indexOf("&", startIndex);
							if(endIndex==-1) {//Client-Charset是最后一个参数
								int sessionidIndex = queryString.indexOf(";", startIndex);//去掉基于URL的SessionID
								if(sessionidIndex!=-1) {
									endIndex = sessionidIndex;
								} else {
									endIndex = queryString.length();
								}
							}
						}
						if(startIndex<endIndex) {
							clientEncoding = queryString.substring(startIndex, endIndex);
							outParam.put("point","自定义HTTP查询参数");
						}
					}
				}
			}
			if(clientEncoding==null || clientEncoding.trim().equals("")) {
				clientEncoding = defaultEncoding;
				outParam.put("point","服务端配置");
			}
			
		}
		return clientEncoding;
	}

 

if (encoding != null) {
			try {
				request.setCharacterEncoding(encoding);//注:被强制认为是GBK编码,好处在于客户端在提交GET请求时不再需要做URLEncode处理了。不好的是,如果客户端提交以UTF-8的编码,则编码出错了。
				//http://www.junlu.com/msg/125726.html
			} catch (Exception e) {
				log.error("Error setting character encoding to '" + encoding
						+ "' - ignoring.", e);
			}
		}
 

测试用例

/modifyListener_test.htm?nick=繁體昵稱衝頂&mobile=13812345678
/modifyListener_test.htm?nick=%B7%B1%F3%77%EA%C7%B7%51%D0%6E%ED%94&mobile=13812345678&Client-Charset=GBK
/modifyListener_test.htm?nick=%E7%B9%81%E9%AB%94%E6%98%B5%E7%A8%B1%E8%A1%9D%E9%A0%82&mobile=13812345678&Client-Charset=UTF-8


/modifyListener_test.htm?nick=涛&mobile=13812345678
/modifyListener_test.htm?nick=%CC%CE&mobile=13812345678&Client-Charset=GBK
/modifyListener_test.htm?nick=%CC%CE&mobile=13812345678
/modifyListener_test.htm?nick=%E6%B6%9B&mobile=13812345678&Client-Charset=UTF-8
/modifyListener_test.htm?nick=%E6%B6%9B&mobile=13812345678  //出错:输入是UTF-8,却被服务器强制为GBK (###nick=娑?,mobile=13812345678)
/modifyListener_test.htm?nick=%E6%B6%9B&mobile=13812345678&Client-Charset=UTF-8;12345
/modifyListener_test.htm?Client-Charset=UTF-8&nick=%E6%B6%9B&mobile=13812345678;12345 //nick=涛,mobile=13812345678;12345


/modifyListener_test.htm?nick=%E6%B6%9B&mobile=13812345678
并设置包头:
Content-Type:    text/html; charset=UTF-8

Content-Type:    charset=UTF-8
//协商或配置的编码:UTF-8,协商源:HTTP标准

 

问题答复:

Passport有一个全局的Filter,强制所有的HTTP请求的编码为GBK,所以支持不了URLEncode(UTF-8)。我想了这么些办法,都不行:
1、    把这个全局的Filter去掉,不强制为GBK,现有线上的那些没有编码的东西支持不了。
这样设置,对于那些没有编码的数据,比如:http://localhost/modifyListener_test.htm?nick=繁體昵稱衝頂&mobile=13812345678 提取的nick则会出错。因此会影响线上其他地方。

2、    手动从GBK再转UTF-8,部分数据能支持,有些不支持。(GBK和UTF-8字符集毕竟不是包含与被包含的关系,其中有冲突的部分)
New String(nick.getBytes(“GBK”),”UTF-8”)  对于http://localhost/modifyListener_test.htm?nick=繁體昵稱衝頂&mobile=13812345678能转换出“繁體昵稱衝頂”;但对于
http://localhost/modifyListener_test.htm?nick=涛&mobile=13812345678  其中“波涛”的“涛”则转换失败。

现在一个可行的解决办法是通过HTTP头协商,需要麻烦你那边在请求中加一个参数:
1、    在HTTP头部增加参数:Content-Type,并设置数值:charset=UTF-8   (备注:在HTTP头里设置Client-Charset参数,数值为UTF-8也行。但前提是Content-Type没被设置为其他)
这样设置后,nick就可以支持URLEncode(UTF-8)了。


2、    对于动态script标签的请求,由于无法设置HTTP头,后台支持查询参数:Client-Charset
比如:这样提交HTTP请求:  nick=%E6%B6%9B&mobile=13812345678&Client-Charset=UTF-8

分享到:
评论

相关推荐

    JAVA过滤器filter request.setCharacterEncoding仅对POST提交起作用,对GET提交还是会出现乱码问题

    标题和描述中提到的问题——"JAVA过滤器filter request.setCharacterEncoding仅对POST提交起作用,对GET提交还是会出现乱码问题",是由于对HTTP协议的理解不足以及不正确的编码设置导致的。下面将详细解释这个问题...

    对Servlet 中 request.setEncoding("utf-8")的分析

    当调用`request.setEncoding("utf-8")`时,实际上是调用了`Request`类的`setCharacterEncoding`方法。这个方法首先检查一个布尔变量`usingReader`。如果`usingReader`为`true`,则意味着已经调用了`getReader()`...

    Jsp页面中的字符编码方式与乱码解决方法

    request.setCharacterEncoding 方法用来指定对客户端请求进行编码的方式。该方法用来指定对浏览器发送来的数据进行编码的编码方式。 4. response.setCharacterEncoding("UTF-8") response.setCharacterEncoding ...

    Tomcat中Get和Post出现乱码的解决办法

    对于 POST 方法,Tomcat 会使用 request.setCharacterEncoding 方法设置的编码来处理,如果未设置,则使用默认的 iso-8859-1 编码。然而,对于 GET 方法,Tomcat 并不会考虑使用 request.setCharacterEncoding 方法...

    Jsp页面中的字符编码方式与乱码解决方法[归类].pdf

    在 JSP/Servlet 中主要有四个地方可以设置编码,分别是 pageEncoding、contentType、request.setCharacterEncoding 和 response.setCharacterEncoding。下面我们将详细介绍每一个编码方式的作用和使用场景。 1. ...

    jsp编码 jsp乱码

    例如,在jsp页面中指定request.setCharacterEncoding("UTF-8"),那么服务器将使用UTF-8编码对客户端请求进行重新编码。 4. 使用response.setCharacterEncoding方法 使用response.setCharacterEncoding方法可以解决...

    JSP在Servlet中的几个编码的作用及原理 .txt

    当客户端发送请求到服务器时,可以通过调用`request.setCharacterEncoding()`方法来指定请求参数的编码格式。例如: ```java request.setCharacterEncoding("UTF-8"); ``` 这样做的目的是确保服务器能够正确解读...

    web乱码解决web乱码解决

    我们可以在JSP文件中设置pageEncoding参数,contentType参数,request.setCharacterEncoding方法和response.setCharacterEncoding方法来指定正确的编码。同时,我们也需要了解浏览器是怎么样对接收和发送的数据进行...

    JSP用户提交页面编码

    通过合理使用`request.setCharacterEncoding()`方法并结合全局配置,可以有效地解决编码问题,提升用户体验。同时,在开发过程中还需要密切关注各种可能引起乱码的因素,确保应用能够稳定运行。

    JSP在Servlet中的几个编码的作用及原理

    与`request.setCharacterEncoding`相对应,`response.setCharacterEncoding`用于设定服务器响应数据的编码方式。这一步骤至关重要,因为即使前端页面和后端处理逻辑中的编码设置都正确,如果响应头中的字符集未正确...

    MyEclipse中文乱码问题简单解决方案,不需任何编码转化

    &lt;%request.setCharacterEncoding("utf-8");%&gt;` 这段代码设置了页面的编码方式为 UTF-8,并将 request 对象的编码方式设置为 UTF-8。 2. 如果使用 Servlet,在 doPost 或 doGet 方法的第一行添加以下代码: `...

    用户管理系统(ums)

    request.setCharacterEncoding("GB18030"); //调用业务逻辑 UserDAO userDAO = new UserDAO(); // 返回的list值 ArrayList list=userDAO.queryAll(); //重点。。。HttpSession的用处??? HttpSession...

    JSP和Servlet中的几个编码的作用及原理

    - **明确指定编码**:尽量避免依赖默认编码设置,明确指定`response.setCharacterEncoding()` 和`request.setCharacterEncoding()`。 通过理解并合理应用这些编码设置,可以显著提高Web应用的稳定性和用户体验。

    解决网页乱码.zip

    而`request.setCharacterEncoding()`和`response.setCharacterEncoding()`则是设置请求和响应的编码方式,通常用于处理POST请求的数据编码。 "setContentType与setCharacterEncoding有什么区别.txt"文件名表明了这...

    Request对象和乱码解决.doc

    通过`request.setCharacterEncoding()`方法可以在接收参数前设置请求的编码格式,例如: ```java request.setCharacterEncoding("gb2312"); String name = request.getParameter("username"); ``` 这种方法更推荐,...

    中文乱码问题分析 自己总结的

    解决这类乱码问题的基本方法是在页面获取参数之前,强制指定 request 获取参数的编码方式:`request.setCharacterEncoding("GBK")` 或 `request.setCharacterEncoding("gb2312")`。 在 Java 与数据库之间的乱码问题...

    tomcat request.getParameter 乱码

    request.setCharacterEncoding("UTF-8"); ``` #### 四、总结 通过对Tomcat服务器的适当配置,可以有效地解决`request.getParameter`方法在处理中文参数时出现的乱码问题。具体而言,通过在`server.xml`文件中...

    中文乱码总结出现的原因,及解决方法,包括数据库乱码

    解决方法是在页面获取参数之前,强制指定 request 获取参数的编码方式:request.setCharacterEncoding("GBK") 或 request.setCharacterEncoding("gb2312") 。 Java 与数据库之间的乱码 Java 和数据库交互时也要...

    jsp乱码问题

    3. **表单提交数据的编码问题**:在处理表单提交的数据时,如果没有正确设置请求的字符编码,如使用`request.setCharacterEncoding()`方法,也会导致乱码。 4. **数据库连接编码设置不当**:如果数据库连接的字符集...

    tomcat与servlet乱码解决办法

    1. **设置请求的字符编码**:使用`request.setCharacterEncoding("UTF-8")`来指定请求参数的编码格式。 2. **设置响应的字符编码**:使用`response.setCharacterEncoding("UTF-8")`设置服务器响应数据的编码。 3. **...

Global site tag (gtag.js) - Google Analytics