2011-10-21 14 views
5

असल में मेरी प्रतिक्रिया हेडरमैं जावा सर्वलेट के भीतर से एक चुस्त प्रतिक्रिया में एचटीपी ट्रेलरों/पाद लेख कैसे भेजूं?

स्थानांतरण एन्कोडिंग = chunked होते हैं,

ट्रेलर = [कुछ ट्रेलर मैं कहता हूँ उदाहरण के लिए "SomeTrailer" भेजना चाहते हैं]

एक बार मैं करने के लिए डेटा लेखन किया कर रहा हूँ सर्वलेट आउटपुटस्ट्रीम, मैं ट्रेलर "कुछ ट्रेलर: [मान]" लिख रहा हूं, लेकिन इसे httpclient द्वारा सही ढंग से पार्स नहीं किया जा रहा है। httpclient पूरे इनपुटस्ट्रीम (ट्रेलर समेत) को एक खंड के रूप में मानता है। मैंने आउटपुटस्ट्रीम पर डेटा लिखा है, लेकिन सफलता के बिना प्रतिक्रिया शीर्षलेख में ट्रेलर लिखने का भी प्रयास किया है।

कृपया मदद

मैं इस पर किसी भी अच्छा स्रोत नहीं मिला है।

+1

क्या यह वास्तव में ग्राहक द्वारा आवश्यक है? 'TE' और' ट्रेलर' का बहुत ही कम उपयोग किया जाता है, मैंने वास्तव में इसे वास्तविक दुनिया कोड में कभी नहीं देखा है। सर्वलेट एपीआई ने खंडित प्रतिक्रियाओं के लिए अंतर्निहित समर्थन किया है (और भी, यह डिफ़ॉल्ट रूप से भेजता है जब आप प्रतिक्रिया की सामग्री लंबाई निर्धारित नहीं करते हैं)। लेकिन इसमें खंडित प्रतिक्रिया ट्रेलरों के लिए अंतर्निहित समर्थन नहीं है। एक विकल्प के रूप में, आप वांछित ट्रेलर के मान को कस्टम प्रतिक्रिया शीर्षलेख के रूप में सेट कर सकते हैं (केवल तभी जब मान यूएस-एएससीआईआई संगत है और एक निश्चित अधिकतम लंबाई से अधिक नहीं है)। – BalusC

+0

@ बालुससी मेरा उपयोग-मामला यह है कि सर्वर डेटा की एक अनंत धारा भेज रहा है और इसकी सामग्री-लंबाई को नहीं जानता है। सर्वर कोड भी फ्लाई पर चेकसम की गणना कर रहा है ताकि वह इसे ट्रेलर के रूप में भेज सके, जिसे क्लाइंट डेटा सत्यापित करने के लिए उपयोग करेगा। –

उत्तर

3

मैंने इसके लिए एक साधारण एकल थ्रेडेड वेबसर्वर लिखना समाप्त कर दिया। बाहर निकला यह काफी आसान था। सर्वर बहुत आसान है। हालांकि कोड थोड़ा मोटा है, लेकिन मुख्य विचार वहां है।

यह फ़ाइलकंट्स को पहले खंड के रूप में और फ़ाइल के चेकसम को एक पाद लेख के रूप में भेजता है।

import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.ServerSocket; 
import java.net.Socket; 

import org.apache.commons.codec.digest.DigestUtils; 
import org.apache.commons.io.IOUtils; 
import org.apache.log4j.Logger; 

public class ChunkedResponseServer implements Runnable { 
    private static final Logger LOGGER = Logger.getLogger(ChunkedResponseServer.class); 

    // Space ' ' 
    static final byte SP = 32; 
    // Tab ' ' 
    static final byte HT = 9; 
    // Carriage return 
    static final byte CR = 13; 
    // Line feed character 
    static final byte LF = 10; 

    final int port; 

    private volatile boolean cancelled = false; 

    public ChunkedResponseServer(int port) { 
    LOGGER.info("Chunked response server running on port " + port); 
    this.port = port; 
    } 

    @Override 
    public void run() { 
    ServerSocket serverSocket = null; 
    try { 
     serverSocket = new ServerSocket(port); 
     while (!cancelled) { 
     final Socket connectionSocket = serverSocket.accept(); 
     handle(connectionSocket); 
     } 
    } catch (final IOException e) { 
     throw new RuntimeException(e); 
    } 
    } 

    public void cancel() { 
    LOGGER.info("Shutting down Chunked response Server"); 
    cancelled = true; 
    } 

    private void handle(Socket socket) throws IOException { 
    BufferedReader input = null; 
    DataOutputStream output = null; 
    try { 
     input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     output = new DataOutputStream(socket.getOutputStream()); 

     addHeaders(output); 
     addCRLR(output); 

     final String filename = readFilename(input); 
     final byte[] content = readContent(filename); 
     addContentAsChunk(output, content); 

     final String checksum = DigestUtils.md5Hex(content); 
     addLastChunkAndChecksumFooter(output, checksum); 
     addCRLR(output); 

    } finally { 
     IOUtils.closeQuietly(input); 
     IOUtils.closeQuietly(output); 
    } 
    } 

    private void addLastChunkAndChecksumFooter(DataOutputStream output, String checksum) throws IOException { 
    output.writeBytes("0"); 
    addCRLR(output); 
    output.writeBytes("checksum: " + checksum); 
    addCRLR(output); 
    } 

    private void addContentAsChunk(DataOutputStream output, byte[] content) throws IOException { 
    output.writeBytes(Integer.toHexString(content.length)); 
    addCRLR(output); 
    output.write(content); 
    addCRLR(output); 
    } 

    private void addCRLR(DataOutputStream output) throws IOException { 
    output.writeByte(CR); 
    output.writeByte(LF); 
    } 

    private void addHeaders(DataOutputStream output) throws IOException { 
    output.writeBytes("HTTP/1.1 200 OK"); 
    addCRLR(output); 
    output.writeBytes("Content-type: text/plain"); 
    addCRLR(output); 
    output.writeBytes("Transfer-encoding: chunked"); 
    addCRLR(output); 
    output.writeBytes("Trailer: checksum"); 
    addCRLR(output); 
    } 

    private String readFilename(BufferedReader input) throws IOException { 
    final String initialLine = input.readLine(); 
    final String filePath = initialLine.split(" ")[1]; 
    final String[] components = filePath.split("/"); 
    return components[components.length - 1]; 
    } 

    private byte[] readContent(String filename) throws IOException { 
    final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename); 
    return IOUtils.toByteArray(in); 
    } 
} 
संबंधित मुद्दे