当使用OkHttp堆栈进行截击请求( StringRequest
或JsonObjectRequest
)时,响应字符串的编码被设置为OkHttp-8995-1,这是默认编码。响应有一个头:content-type=text/html; charset=utf-8
,它应该被检测到。为什么不是呢?
发布于 2013-10-09 17:10:27
这两种请求类型都调用HttpHeaderParser.parseCharset
,它能够从头部确定字符集。但是,它要求标头是Content-Type
,而不是content-type
:它区分大小写。(我不确定使用默认HurlStack时的行为,这可能是与OkHttp堆栈在实现细节上的不同。)
方案一:复制原始请求类型,但手动覆盖字符集
解决方案2:复制原始请求类型,但强制存在期望的头部
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));
}
}
}
发布于 2013-12-11 20:57:29
首先,感谢alot @mjibson在这里发布的两个解决方案,我遇到了类似的问题,在我的例子中,内容类型总是丢失,所以如下所示:
protected static final String TYPE_UTF8_CHARSET = "charset=UTF-8";
@Override
protected Response<String> parseNetworkResponse(
NetworkResponse response) {
try {
String type = response.headers.get(HTTP.CONTENT_TYPE);
if (type == null) {
Log.d(LOG_TAG, "content type was null");
type = TYPE_UTF8_CHARSET;
response.headers.put(HTTP.CONTENT_TYPE, type);
} else if (!type.contains("UTF-8")) {
Log.d(LOG_TAG, "content type had UTF-8 missing");
type += ";" + TYPE_UTF8_CHARSET;
response.headers.put(HTTP.CONTENT_TYPE, type);
}
} catch (Exception e) {
//print stacktrace e.g.
}
return super.parseNetworkResponse(response);
}
我只是想把这个分享给其他遇到类似问题的人。阅读https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/HttpHeaderParser.java中的parseCharset方法以了解其工作原理也很重要
发布于 2014-03-28 01:14:24
重写Request<T>
类的方法parseNetworkResponse
。
你可以这样做:
/**
* A canned request for retrieving the response body at a given URL as a String.
*/
public class StringRequest extends Request<String> {
private final Listener<String> mListener;
/**
* the parse charset.
*/
private String charset = null;
/**
* Creates a new request with the given method.
*
* @param method the request {@link Method} to use
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public StringRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
/**
* Creates a new GET request.
*
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
/**
* Creates a new GET request with the given Charset.
*
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public StringRequest(String url, String charset, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
this.charset = charset;
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
if(charset != null) {
parsed = new String(response.data, charset);
} else {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
}
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
/**
* @return the Parse Charset Encoding
*/
public String getCharset() {
return charset;
}
/**
* set the Parse Charset Encoding
* @param charset
*/
public void setCharset(String charset) {
this.charset = charset;
}
}
https://stackoverflow.com/questions/19267616
复制相似问题