2012-02-29 4 views
2

JSON 데이터로 응답하는 간단한 Java HTTP 서버를 작성하고 있습니다. 그것을 보내기 전에 데이터를 GZip하려고하지만 일반적으로 브라우저에 오류를 생성하는 gzipped 데이터를 보냅니다. 예를 들어, Firefox에서 다음과 같이 말합니다 :GZIPOutputStream이 HTTP 응답의 문자열을 올바르게 압축하지 않습니다.

콘텐츠 인코딩 오류 유효하지 않거나 지원되지 않는 압축 형식을 사용하기 때문에 보려고하는 페이지를 표시 할 수 없습니다.

때로는 압축하는 문자열이 특정 문자가 없으면 작지만 대괄호 등이있을 때 엉망이되는 경우가 있습니다. 특히 아래에있는 예제 텍스트가 실패합니다.

이 문자 인코딩 문제입니까? 나는 모든 종류의 일을 시도했지만, 단지 쉽게 일하고 싶지 않습니다.

String text;    
private Socket server; 
DataInputStream in = new DataInputStream(server.getInputStream()); 
PrintStream out = new PrintStream(server.getOutputStream()); 

while ((text = in.readLine()) != null) { 
    // ... process header info 
    if (text.length() == 0) break; 
} 

out.println("HTTP/1.1 200 OK"); 
out.println("Content-Encoding: gzip"); 
out.println("Content-Type: text/html"); 
out.println("Connection: close"); 


// x is the text to compress 
String x = "jsonp1330xxxxx462022184([["; 
ByteArrayOutputStream outZip = new ByteArrayOutputStream(); 
GZIPOutputStream gzip = new GZIPOutputStream(outZip); 

byte[] b = x.getBytes(); // Changing character encodings here makes no difference 

gzip.write(b); 
gzip.finish(); 
gzip.close(); 
outZip.close(); 
out.println(); 
out.print(outZip); 
server.close(); 
+0

Jusr curious, 어느 서버를 사용하고 있습니까? 이러한 설정은 서버 수준에서 더 쉽게 수행 할 수 있습니다. 예 : tomcat의 경우, 콘텐츠 유형'application/json'에 대해'gzip' 압축을 활성화해야만합니다. 또는 첫 성명서에서 말하는 바와 같이 실제로 서버를 작성하고 있습니까? – Nikhil

+1

내용 이전에 마지막 응답 헤더 행 다음에 "CRLF"가 누락되었습니다. – Bombe

+0

의견을 보내 주셔서 감사합니다. 실제로는 간단한 작업이므로 내 서버를 실제로 작성하고 있습니다. 포트를 열고 Javascript JSONP 요청에서 수신 대기합니다. 실제 보안 상 의미가 없기를 바랍니다. CRLF에 관해서는 아래쪽에있는 것 같습니다. out.println(); – DFx

답변

2

반 직관적으로 GZIPOutputStream은 스트리밍에 적합하지 않습니다. 사용해보기 :

... 
out.println("Content-Encoding: deflate"); // NOTICE deflate encoding 
out.println("Content-Type: text/html"); 
out.println("Connection: close"); 
out.println(); 
String x = "jsonp1330xxxxx462022184([["; 
DeflaterInputStream dis = new DeflaterInputStream(out); 
dis.write(x.getBytes("utf-8")); // JSON is UTF-8 
dis.close(); 
server.close(); // this a bad idea, the client may not have read the data yet 
+0

감사! DeflaterInputStream을 DeflaterOutputStream으로 변경해야했지만 매력적이었습니다! 서버 연결을 닫기 전에 무엇을 기다려야합니까? 이런 식으로 작동하는 것 같지만, 당신이 말했듯이, 나는 조기에 랜덤 드랍이 발생하는 것을 원하지 않습니다. – DFx

+0

실제로 소켓을 닫기 전에 출력 스트림 (귀하의 경우에는 '출력')을 flush()하면 좋을 것입니다. 만족 스럽다면이 답을 표시하십시오. – brettw

+0

도움 주셔서 감사합니다! – DFx

관련 문제