2014-05-15 16 views
5

Sto utilizzando HttpClient (versione 3.1) su diversi computer diversi (ma apparentemente identici) per leggere i dati JSON codificati in UTF-8 da un URL.HttpClient che ignora la codifica, su un singolo computer

Su tutte le macchine, tranne una, funziona correttamente. Ho alcune parole in lingua spagnola e vengono fornite con accenti e tilde intatti.

Un computer si rifiuta ostinatamente di collaborare. A quanto pare, i dati vengono trattati come ISO-8859-1, nonostante l'intestazione Content-Type: application/json;charset=utf-8.

Se utilizzo curl per accedere a quell'URL da quel computer, funziona correttamente. Su ogni altro computer, sia il ricciolo che il mio programma HttpClient funzionano correttamente.

Ho fatto un md5sum sul file common-httpclient.jar su ogni macchina: lo stesso.

C'è qualche impostazione, in profondità in Linux, che potrebbe essere diversa e fare casino con me? Altre teorie, o anche luoghi da guardare?

MODIFICA: alcune persone hanno chiesto ulteriori dettagli.

Originariamente avevo il problema nelle viscere di una complessa app Tomcat, ma ho adattato leggermente lo the sample per recuperare l'URL in questione e (fortunatamente) avevo lo stesso problema.

Queste sono macchine Linux 2.6 che eseguono jdk1.7.0_45.

Un comando env produce un sacco di variabili. L'unico che appare da remoto è LANG=en_US.UTF-8.

+0

potresti spiegare un po 'di più sulla macchina su cui non funziona, è un linux? quale? – caramba

+0

Puoi chiarire la configurazione? È un problema con il client della riga di comando che utilizza httpclient per accedere ad alcuni URL? Quali variabili ambientali del sistema locale sono impostate su questo computer? –

+0

risposta @caramba in modifica. – Malvolio

risposta

5

Come si ottengono i dati di risposta JSON da HttpClient?

Se si ottiene di nuovo in forma binaria (attraverso getResponseBodyAsStream() per esempio), e quindi convertirlo in una stringa senza specificare charset, poi il risultato dipende charset predefinito del JVM.

È possibile controllare il valore di JVM charset predefinito:

Charset.defaultCharset().name() 

Questo potrebbe dare "UTF-8" su tutte le macchine tranne quello fallendo.

2

Senza vedere il tuo codice, è difficile dire cosa c'è che non va, ma qui c'è un modo "corretto" per farlo (usando HttpClient 3.1.0 per la richiesta e Jackson 2.1.3 per analizzare il JSON).

import com.fasterxml.jackson.core.JsonFactory; 
import com.fasterxml.jackson.databind.JsonNode; 
import com.fasterxml.jackson.databind.ObjectMapper; 

import org.apache.commons.httpclient.HttpClient; 
import org.apache.commons.httpclient.methods.GetMethod; 
import org.apache.http.HttpStatus; 

import java.io.IOException; 
import java.io.InputStreamReader; 

HttpClient hc = new HttpClient(); 
GetMethod get = new GetMethod(uri); 
int status = hc.executeMethod(get); 
if (status != HttpStatus.SC_OK) throw new RuntimeException("http status " + status); 
ObjectMapper jsonParser = new ObjectMapper(new JsonFactory()); 
// we use an InputStreamReader with explicit charset to read the response body 
JsonNode json = jsonParser.readTree(
    new InputStreamReader(get.getResponseBodyAsStream(), get.getResponseCharSet()) 
); 
2

Ho già affrontato questo problema e questo è stato a causa del tipo di codifica configurata nel client. Così ho dovuto fare una "aggirare" come quella qui sotto:

String encmsg = new String(respStr.getBytes("ISO-8859-1"), java.nio.charset.Charset.forName("UTF-8")); 

Si legge la stringa come ISO-8859-1 e convertire in UTF-8.