为什么 volley 的响应字符串使用与响应标头中的编码不同的编码? [英] Why does volley's response string use an encoding different from that in the response headers?
问题描述
在执行 volley 请求(StringRequest
或 JsonObjectRequest
)时,使用 OkHttp 堆栈,响应字符串的编码设置为 ISO-8995-1,即默认编码.响应有一个标题:content-type=text/html;charset=utf-8
,应该被检测到.为什么不是?
When doing a volley request (either StringRequest
or JsonObjectRequest
), using the OkHttp stack, the response string's encoding is set to ISO-8995-1, which is the default encoding. The response has a header: content-type=text/html; charset=utf-8
, which should be detected. Why isn't it?
推荐答案
这两种请求类型都调用 HttpHeaderParser.parseCharset
,它能够从标题中确定字符集.但是,它要求标头是 Content-Type
,而不是 content-type
:它区分大小写.(我不确定使用默认 HurlStack 时的行为,这可能是与 OkHttp 堆栈的实现细节差异.)
Both of those request types call HttpHeaderParser.parseCharset
, which is able to determine the charset from the headers. However, it requires that the header be Content-Type
, not content-type
: it is case sensitive. (I'm not sure of the behavior if using the default HurlStack, it's possible this is an implementation detail difference with the OkHttp stack.)
方案一:复制原始请求类型,但手动覆盖字符集
Solution 1: copy the original request type, but manually override the charset
方案二:复制原请求类型,但强制要求的header存在
Solution 2: copy the original request type, but force the expected header to exist
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
public class JsonUTF8Request extends JsonRequest<JSONObject> {
public JsonUTF8Request(int method, String url, JSONObject jsonRequest,
Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
// solution 1:
String jsonString = new String(response.data, "UTF-8");
// solution 2:
response.headers.put(HTTP.CONTENT_TYPE,
response.headers.get("content-type"));
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
//
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
这篇关于为什么 volley 的响应字符串使用与响应标头中的编码不同的编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!