2013-10-09 15 views

risposta

32

Entrambi i tipi di richiesta chiamano HttpHeaderParser.parseCharset, che è in grado di determinare il set di caratteri dalle intestazioni. Tuttavia, richiede che l'intestazione sia Content-Type, non content-type: è case sensitive. (Non sono sicuro del comportamento se si utilizza il default HurlStack, è possibile si tratta di una differenza di dettaglio di implementazione con lo stack OkHttp.)

Soluzione 1: copiare il tipo di richiesta originale, ma sostituire manualmente il set di caratteri

Soluzione 2: copiare il tipo di richiesta originale, ma forzare l'intestazione dovrebbe esistere

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

grazie aiutato. –

+0

Uomo, mi hai salvato la giornata! Molte grazie! – Roman

+0

questa è una domanda vecchia, ma se aiuta oggi, puoi unire entrambe le soluzioni in una sola. String jsonString = new String (response.data, HttpHeaderParser.parseCharset (response.headers, "UTF-8")); In questo modo è possibile impostare il set di caratteri predefinito se non esiste nessuno. – hmartinezd

12

Innanzitutto grazie a lot @mjibson per le 2 soluzioni hai postato qui, ho avuto un problema simile, nel mio caso il tipo di contenuto è stato manca sempre così ha fatto quanto segue:

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

volevo solo condividere questo per gli altri per imbattersi in un problema simile. è inoltre importante leggere il metodo parseCharset in https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/HttpHeaderParser.java per ottenere il motivo per cui funziona

3

Ignorare il metodo parseNetworkResponse della classe Request<T>.
Si può fare in questo modo:

/** 
* 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

cambiare il metodo da GET POST per 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

Grazie @Simon Heinen. In base alla tua risposta, ho scritto una funzione.

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

utilizzati:

protected Response<String> parseNetworkResponse(NetworkResponse response) { 
      addEncodeing2Request(response); 
      return super.parseNetworkResponse(response); 
     } 

Inoltre, ignorare getParamsEncoding() può anche funzionare.

protected String getParamsEncoding() { 
      return "utf-8"; 
     } 
Problemi correlati