2013-10-09 6 views
17

ओकेएचटीपी स्टैक का उपयोग करते हुए, वॉली अनुरोध (या तो StringRequest या JsonObjectRequest) करते समय, प्रतिक्रिया स्ट्रिंग का एन्कोडिंग ISO-8995-1 पर सेट होता है, जो डिफ़ॉल्ट एन्कोडिंग होता है। प्रतिक्रिया में हेडर है: content-type=text/html; charset=utf-8, जिसे पता लगाया जाना चाहिए। यह क्यों नहीं हैवॉली की प्रतिक्रिया स्ट्रिंग प्रतिक्रिया शीर्षकों में से अलग एन्कोडिंग का उपयोग क्यों करती है?

उत्तर

32

उन दोनों अनुरोध प्रकारों को HttpHeaderParser.parseCharset पर कॉल करें, जो शीर्षलेखों से वर्णमाला निर्धारित करने में सक्षम हैं। हालांकि, यह आवश्यक है कि हेडर Content-Type हो, content-type नहीं: यह मामला संवेदनशील है। (मैं व्यवहार के बारे में सुनिश्चित करती है कि डिफ़ॉल्ट HurlStack का उपयोग नहीं कर रहा हूँ, यह संभव है इस OkHttp ढेर के साथ एक कार्यान्वयन विस्तार अंतर है।)

समाधान 1: नकल मूल अनुरोध प्रकार, लेकिन मैन्युअल रूप से ओवरराइड चारसेट

समाधान 2: मूल अनुरोध प्रकार की नकल, लेकिन 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)); 
     } 
    } 
} 
+0

धन्यवाद इससे मदद मिली। –

+0

मैन, तुम मेरा दिन बचाओ! आपका बहुत बहुत धन्यवाद! – Roman

+0

यह एक पुराना सवाल है, लेकिन अगर यह आज मदद करता है, तो आप दोनों समाधानों को एक में मिश्रित कर सकते हैं। स्ट्रिंग jsonString = नया स्ट्रिंग (प्रतिक्रिया.data, HttpHeaderParser.parseCharset (response.headers, "UTF-8")); यदि कोई मौजूद नहीं है तो आप डिफ़ॉल्ट वर्णसेट सेट कर सकते हैं। – hmartinezd

12

@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 में पार्स चार्सेट विधि को पढ़ने के लिए भी महत्वपूर्ण है, यह

3

Request<T> कक्षा के parseNetworkResponse को ओवरराइड करें। 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()); 
       } 
      }); 

के लिए पोस्ट करने के लिए मिल से

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

बदलें विधि:
आप इस तरह कर सकते हैं। । । ।

0

धन्यवाद @ सिमन हेनन। आपके उत्तर के आधार पर, मैंने एक समारोह लिखा था।

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

उपयोग:

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

इसके अलावा, getParamsEncoding() ओवरराइड भी काम कर सकते हैं।

protected String getParamsEncoding() { 
      return "utf-8"; 
     } 
संबंधित मुद्दे