2014-02-19 2 views
2

Android 모바일 앱에서 HTTP 게시물을 통해 XML 메시지를 서버로 보내려고합니다.Android의 HttpUrlConnection 인코딩 문제

URL url = new URL(vURL); 

HttpUrlConnection conn = (HttpURLConnection) url.openConnection(); 

conn.setDoInput(true); 
conn.setDoOutput(true); 

// Adding headers (code removed) 

conn.setRequestProperty("Content-Type", "text/xml; charset=utf-16"); 
OutputStream out = new BufferedOutputStream(conn.getOutputStream()); 

// Adding XML message to the connection output stream 
// I have removed exception handling to improve readability for posting it here 
out.write(pReq.getBytes()); // here pReq is the XML message in String 
out.close(); 

conn.connect(); 

나는 응답을하면, 스트림을 읽는 부분은이 방식으로 수행됩니다 :

나는 다음 단계를 수행하여, HttpURLConnection의 그것을 시도

BufferedReader in = null; 
StringBuffer sb; 
String result = null; 

    try { 

     InputStreamReader isr = new InputStreamReader(is); 
      // Just in case, I've also tried: 
      // new InputStreamReader(is, "UTF-16"); 
      // new InputStreamReader(is, "UTF-16LE"); 
      // new InputStreamReader(is, "UTF-16BE"); 
      // new InputStreamReader(is, "UTF-8"); 

     in = new BufferedReader(isr); 

     sb = new StringBuffer(""); 
     String line = ""; 

     while ((line = in.readLine()) != null) 
      sb.append(line); 

     in.close(); 

     result = sb.toString(); 

    } catch (Exception e) { 

     e.printStackTrace(); 
    } 

이제 결과 문자열을 I get은 읽을 수없는 형식/인코딩입니다.

HttpClient를 사용하여 동일한 작업을 시도하면 제대로 작동합니다. 일부 도움이 문제를 이해 감사

BufferedReader in = null; 
    InputStream   is; 
    StringBuffer sb; 
    String decompbuff = null; 

    try { 

     is = pResponse.getEntity().getContent(); 
     InputStreamReader isr = new InputStreamReader(is); 
     in = new BufferedReader(isr); 

     // Prepare the String buffer 
     sb = new StringBuffer(""); 

     String line = ""; 

     while ((line = in.readLine()) != null) 
      sb.append(line); 

     in.close(); 

     // gZip decompression of response. Note: message was compressed before 
     // posting it via HttpClient (Posting code is not mentioned here) 
     decompbuff = Decompress(sb.toString()); 

    } catch (Exception e) { 

     e.printStackTrace(); 
    } 

    return decompbuff; 

: 나는 HttpClient.execute 호출 후 HttpResponse에를 일단 여기에 스트리밍 읽기 부분입니다.

+1

'쓰기 스트림 (출력);'구현을 보여줄 수 있습니까? 스트림을 닫고 있습니까? UTF16이 실제로 있습니까? 리틀 또는 빅 엔디안? BOM 사용 여부는? 응답은 어떻게 생겼습니까? HttpClient와 작동하는 코드를 보여줄 수 있습니까? – hgoebl

+0

귀하의 질문에 대한 답변 : 스트림을 쓰고 난 후 닫고 있습니다. 몇 분 안에 HttpClient와 함께 작동하는 코드를 게시 할 것입니다. "결과"문자열에 나타나는 응답은 '중국어 문자'처럼 보입니다. :) 나는 당신이 의미하는 바를 이해하지 못했습니다. "당신은 실제로 UTF 16을 가집니까 ..." – sg1

답변

1

하나의 (심각한) 문제는 입력 및 출력의 인코딩을 무시하는 것일 수 있습니다.

입력

conn.setRequestProperty("Content-Type", "text/xml; charset=utf-16"); 
OutputStream out = new BufferedOutputStream(conn.getOutputStream()); 

// Adding XML message to the connection output stream 
// I have removed exception handling to improve readability for posting it here 
out.write(pReq.getBytes()); // <-- you use standard platform encoding 
out.close(); 

더 나은 : (DavidWebb에서 촬영) 더 나은 같을 것이다 당신은 아마 압축을 무시

out.write(pReq.getBytes("UTF-16")); 

출력 :

static InputStream wrapStream(String contentEncoding, InputStream inputStream) 
     throws IOException { 
    if (contentEncoding == null || "identity".equalsIgnoreCase(contentEncoding)) { 
     return inputStream; 
    } 
    if ("gzip".equalsIgnoreCase(contentEncoding)) { 
     return new GZIPInputStream(inputStream); 
    } 
    if ("deflate".equalsIgnoreCase(contentEncoding)) { 
     return new InflaterInputStream(inputStream, new Inflater(false), 512); 
    } 
    throw new RuntimeException("unsupported content-encoding: " + contentEncoding); 
} 

// ... 

    InputStream is = wrapStream(conn.getContentEncoding(), is); 
    InputStreamReader isr = new InputStreamReader(is, "UTF-16"); 

    in = new BufferedReader(isr); 

    sb = new StringBuffer(""); 
    String line = ""; 

    while ((line = in.readLine()) != null) 
     sb.append(line); // <-- you're swallowing linefeeds! 

    in.close(); 
    result = sb.toString(); 

XML 파서가 InputStream을 직접 사용하게하는 것이 좋습니다. JAVA 문자열을 만들지 말고 파서가 바이트를 검색하도록합니다. 자동으로 XML의 인코딩을 감지합니다.

일반적으로 사용하는 UTF-16 유형을 알 수 없기 때문에 문제가있을 수 있습니다. BigEndian 또는 LittleEndian이 될 수 있습니다. 그것이 UTF-16이 정말로 필요한지 물어 본 이유입니다. 일부 아시아 언어로 치료할 필요가 없다면 UTF-8이 더 효율적이고 사용하기 쉬워야합니다.

내가 준 "해결책"은 작동하지 않을 수도 있습니다. UTF-16 BE/LE로 약간의 실수를해야합니다. 행운과 인내심을 기원합니다.

위의 예에서 위의 예에서는 문자열을 먼저 구성한 다음 문자열을 구성합니다. 그것은 잘못된 순서입니다. 스트림은 압축되어 (gzip, deflate) 먼저 압축을 풀어야합니다. 그런 다음 문자열을 가져옵니다.