Lorsque vous effectuez une requête de volée (StringRequest
ou JsonObjectRequest
), à l'aide de la pile OkHttp, le codage de la chaîne de réponse est défini sur ISO-8995-1, qui est le codage par défaut. La réponse a un en-tête: content-type=text/html; charset=utf-8
, qui doit être détecté. Pourquoi n'est-ce pas?Pourquoi la chaîne de réponse de volley utilise-t-elle un codage différent de celui des en-têtes de réponse?
Répondre
Ces deux types de requêtes appellent HttpHeaderParser.parseCharset
, qui est capable de déterminer le jeu de caractères à partir des en-têtes. Cependant, il faut que l'en-tête soit Content-Type
, et non content-type
: il est sensible à la casse. (Je ne suis pas sûr du comportement si vous utilisez la valeur par défaut HurlStack, il est possible que c'est une différence de détail de mise en œuvre avec la pile de OkHttp.)
Solution 1: copier le type de demande initiale, mais remplacer manuellement le charset
Solution 2: copier le type de demande initiale, mais la force l'en-tête devrait exister
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));
}
}
}
Première merci beaucoup @mjibson pour les 2 solutions vous avez posté ici, j'ai eu un problème similaire, dans mon cas, le type de contenu était toujours manquant ainsi fait ce qui suit:
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);
}
Je voulais juste partager ceci pour que d'autres se heurtent à un problème similaire. il est également important de lire la méthode parseCharset dans https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/HttpHeaderParser.java pour savoir pourquoi cela fonctionne
Surchargez la méthode parseNetworkResponse
de la classe Request<T>
.
Vous pouvez faire comme ceci:
/**
* 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;
}
}
changer la méthode de GET à POST pour UTF-8 suppport
JsonObjectRequest jsonReq = new JsonObjectRequest(Method.POST,
URL_FEED, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
VolleyLog.d(TAG, "Response: " + response.toString());
Log.d("SHY", "Response: " + response.toString());
if (response != null) {
parseJsonFeed(response);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
. . . .
Merci @Simon Heinen. Sur la base de votre réponse, j'ai écrit une fonction.
private void addEncodeing2Request(NetworkResponse response) {
try {
String type = response.headers.get(HTTP.CONTENT_TYPE);
if (type == null) {
//Content-Type:
Log.d("RVA", "content type was null");
type = TYPE_UTF8_CHARSET;
response.headers.put(HTTP.CONTENT_TYPE, type);
} else if (!type.contains("charset")) {
//Content-Type: text/plain;
Log.d("RVA", "charset was null, added encode utf-8");
type += ";" + TYPE_UTF8_CHARSET;
response.headers.put(HTTP.CONTENT_TYPE, type);
} else {
//nice! Content-Type: text/plain; charset=utf-8'
Log.d("RVA", "charset is " + type);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Utilisation:
protected Response<String> parseNetworkResponse(NetworkResponse response) {
addEncodeing2Request(response);
return super.parseNetworkResponse(response);
}
En outre, passer outre getParamsEncoding() peut également fonctionner.
protected String getParamsEncoding() {
return "utf-8";
}
- 1. Rendre un programme en attente de la réponse de Volley
- 2. Codage de réponse d'échantillon JMeter
- 3. ajouter des entêtes google volley demande?
- 4. Rails Codage de réponse Json
- 5. Parse réponse Android JSONArray Volley
- 6. jquery: type de réponse différent
- 7. Problème de codage avec la réponse ASIHttpRequest
- 8. Problème de codage de réponse SOAP
- 9. Android Volley renvoie la valeur de la réponse
- 10. Réponse venant de Volley la première fois seulement
- 11. La réponse XML contient un codage HTML sur la réponse de l'API
- 12. Manipulation de délai de réponse dans android en utilisant volley
- 13. Wrapper pour le codage de réponse HTTP
- 14. déterminant le codage de réponse du serveur
- 15. Problème de codage de réponse de service Web
- 16. compression gzip de la réponse de codage en bloc?
- 17. Null Point Exception - Android Volley Réponse
- 18. BasicNetwork.performRequest: code de réponse inattendue 400 pour l'URL (POST) volley
- 19. Volley ne pas retourner la réponse à l'activité principale
- 20. Encodage de chaîne Conversation dans la réponse JSON
- 21. Obtenir une réponse invalide retour de la réponse Ajax
- 22. Littéral de chaîne de réponse Python AJAX
- 23. C# N'obtenant pas de réponse appropriée de HttpWebResponse. Codage?
- 24. tableau Extraction de chaîne de réponse
- 25. Codage de réponse différent REST utilisant JAVA entre mon hôte local et Mon serveur
- 26. () retourne résultat différent de celui prévu
- 27. Android - Utilisation de Volley pour afficher un listview personnalisé Erreur dans la réponse
- 28. Définition d'un message de réponse différent dans Python email/smtplib
- 29. Comment obtenir des valeurs particulières à partir des données de réponse Volley JSON à l'aide d'Android?
- 30. Pourquoi java AudioSystem.getTargetEncodings (AudioFormat) renvoie-t-il un codage différent de celui de l'AudioFormat que nous fournissons?
merci cela a aidé. –
Homme, tu sauves ma journée! Merci beaucoup! – Roman
C'est une vieille question, mais si cela vous aide aujourd'hui, vous pouvez mélanger les deux solutions en une seule. Chaîne jsonString = nouvelle chaîne (response.data, HttpHeaderParser.parseCharset (response.headers, "UTF-8")); De cette façon, vous pouvez définir le jeu de caractères par défaut si aucun n'existe. – hmartinezd