2013-10-09 3 views

Répondre

32

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)); 
     } 
    } 
} 
+0

merci cela a aidé. –

+0

Homme, tu sauves ma journée! Merci beaucoup! – Roman

+0

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

12

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

3

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; 
    } 

} 
3

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()); 
       } 
      }); 

. . . .

0

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"; 
     } 
Questions connexes