2011-07-23 109 views
2

首先,我的问题是关于Java中的HttpServer处理来自客户端的POST请求,而不是关于可以将文件上传到Web服务器的Java客户端。如何让Java HttpServer处理Post请求文件上传

好的。我在Java中使用轻量级HttpServer来处理“GET”|| “POST”请求。 HttpServer的源代码从http://www.prasannatech.net/2008/11/http-web-server-java-post-file-upload.html复制而来。

/* 
* HTTPPOSTServer.java 
* Author: S.Prasanna 
* @version 1.00 
*/ 

import java.io.*; 
import java.net.*; 
import java.util.*; 

public class HTTPPOSTServer extends Thread { 

    static final String HTML_START = 
     "<html>" + 
     "<title>HTTP POST Server in java</title>" + 
     "<body>"; 

    static final String HTML_END = 
     "</body>" + 
     "</html>"; 

    Socket connectedClient = null;  
    BufferedReader inFromClient = null; 
    DataOutputStream outToClient = null; 


    public HTTPPOSTServer(Socket client) { 
     connectedClient = client; 
    }    

    public void run() { 

     String currentLine = null, postBoundary = null, contentength = null, filename = null, contentLength = null; 
     PrintWriter fout = null; 

     try { 

      System.out.println("The Client "+ 
        connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected"); 

      inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));     
      outToClient = new DataOutputStream(connectedClient.getOutputStream()); 

      currentLine = inFromClient.readLine(); 
      String headerLine = currentLine;     
      StringTokenizer tokenizer = new StringTokenizer(headerLine); 
      String httpMethod = tokenizer.nextToken(); 
      String httpQueryString = tokenizer.nextToken(); 

      System.out.println(currentLine); 

      if (httpMethod.equals("GET")) {  
       System.out.println("GET request");   
       if (httpQueryString.equals("/")) { 
        // The default home page 
        String responseString = HTTPPOSTServer.HTML_START + 
         "<form action=\"http://127.0.0.1:5000\" enctype=\"multipart/form-data\"" + 
         "method=\"post\">" + 
         "Enter the name of the File <input name=\"file\" type=\"file\"><br>" + 
         "<input value=\"Upload\" type=\"submit\"></form>" + 
         "Upload only text files." + 
         HTTPPOSTServer.HTML_END; 
        sendResponse(200, responseString , false);         
       } else { 
        sendResponse(404, "<b>The Requested resource not found ...." + 
          "Usage: http://127.0.0.1:5000</b>", false);     
       } 
      } 
      else { //POST request 
       System.out.println("POST request"); 
       do { 
        currentLine = inFromClient.readLine(); 

        if (currentLine.indexOf("Content-Type: multipart/form-data") != -1) { 
         String boundary = currentLine.split("boundary=")[1]; 
         // The POST boundary       

         while (true) { 
          currentLine = inFromClient.readLine(); 
          if (currentLine.indexOf("Content-Length:") != -1) { 
           contentLength = currentLine.split(" ")[1]; 
           System.out.println("Content Length = " + contentLength); 
           break; 
          }      
         } 

         //Content length should be < 2MB 
         if (Long.valueOf(contentLength) > 2000000L) { 
          sendResponse(200, "File size should be < 2MB", false); 
         } 

         while (true) { 
          currentLine = inFromClient.readLine(); 
          if (currentLine.indexOf("--" + boundary) != -1) { 
           filename = inFromClient.readLine().split("filename=")[1].replaceAll("\"", "");           
           String [] filelist = filename.split("\\" + System.getProperty("file.separator")); 
           filename = filelist[filelist.length - 1];       
           System.out.println("File to be uploaded = " + filename); 
           break; 
          }      
         } 

         String fileContentType = inFromClient.readLine().split(" ")[1]; 
         System.out.println("File content type = " + fileContentType); 

         inFromClient.readLine(); //assert(inFromClient.readLine().equals("")) : "Expected line in POST request is "" "; 

         fout = new PrintWriter(filename); 
         String prevLine = inFromClient.readLine(); 
         currentLine = inFromClient.readLine();    

         //Here we upload the actual file contents 
         while (true) { 
          if (currentLine.equals("--" + boundary + "--")) { 
           fout.print(prevLine); 
           break; 
          } 
          else { 
           fout.println(prevLine); 
          }  
          prevLine = currentLine;      
          currentLine = inFromClient.readLine(); 
         } 

         sendResponse(200, "File " + filename + " Uploaded..", false); 
         fout.close();     
        } //if            
       }while (inFromClient.ready()); //End of do-while 
      }//else 
     } catch (Exception e) { 
      e.printStackTrace(); 
     }  
    } 

    public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception { 

     String statusLine = null; 
     String serverdetails = "Server: Java HTTPServer"; 
     String contentLengthLine = null; 
     String fileName = null;   
     String contentTypeLine = "Content-Type: text/html" + "\r\n"; 
     FileInputStream fin = null; 

     if (statusCode == 200) 
      statusLine = "HTTP/1.1 200 OK" + "\r\n"; 
     else 
      statusLine = "HTTP/1.1 404 Not Found" + "\r\n";  

     if (isFile) { 
      fileName = responseString;    
      fin = new FileInputStream(fileName); 
      contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n"; 
      if (!fileName.endsWith(".htm") && !fileName.endsWith(".html")) 
       contentTypeLine = "Content-Type: \r\n";  
     }       
     else { 
      responseString = HTTPPOSTServer.HTML_START + responseString + HTTPPOSTServer.HTML_END; 
      contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";  
     }    

     outToClient.writeBytes(statusLine); 
     outToClient.writeBytes(serverdetails); 
     outToClient.writeBytes(contentTypeLine); 
     outToClient.writeBytes(contentLengthLine); 
     outToClient.writeBytes("Connection: close\r\n"); 
     outToClient.writeBytes("\r\n");   

     if (isFile) sendFile(fin, outToClient); 
     else outToClient.writeBytes(responseString); 

     outToClient.close(); 
    } 

    public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception { 
     byte[] buffer = new byte[1024] ; 
     int bytesRead; 

     while ((bytesRead = fin.read(buffer)) != -1) { 
      out.write(buffer, 0, bytesRead); 
     } 
     fin.close(); 
    } 

    public static void main (String args[]) throws Exception { 

     ServerSocket Server = new ServerSocket (5000);   
     System.out.println ("HTTP Server Waiting for client on port 5000"); 

     while(true) {           
      Socket connected = Server.accept(); 
      (new HTTPPOSTServer(connected)).start(); 
     }  
    } 
} 

我通过代码阅读,我认为代码应该没问题。

但是当我尝试上传一个文件时,它会打印出POST请求,然后挂在那里,永远不会收到任何字节。

如果您愿意,您可以直接运行上述源代码。启动后,你可以在浏览器中输入127.0.0.1:5000,它会显示一个文件上传,然后如果我尝试上传一个文件,它会在打印PoST请求后挂在那里。

如果您厌倦了阅读代码,我可以问以下更简单的问题吗?

那么,Chrome或任何其他网络浏览器做什么关于窗体 - > input type ='file'?

如果我使用ServerSocket来处理HTTP请求,我只需要获取请求的InputStream,然后所有的内容(包括HTTP标头&的上传文件的内容)都会经过该InputStream,对吧?

上面的代码可以分析标题,但似乎没有什么是从浏览器发送。

任何人都可以帮忙吗?

感谢

+0

你找到这个答案? – Sridharan

回答

2

它挂起,因为客户端(浏览器,在我的情况)不提供Content-LengthRFC 1867对此很含糊。它有点暗示它,但不强制它,并没有一个例子。显然,客户不会总是发送它。代码应防止丢失长度。相反,它会经历循环,直到达到文件末尾。然后它挂起。

使用调试器有时会非常有用。

0

那是一个洛塔代码:)

让被轻易移动break;调用出来的,如果支柱部内声明,开始与线83。我们需要弄清楚什么是挂那些while语句可以开始成为问题。

这将帮助我们找出问题所在。

如果你只是想让它工作,而不是真的在意这个bug是什么,这就是重新发明轮子,有很多图书馆在那里做一两行操作。

这里有一个很好的一个:http://www.servlets.com/cos/ - 看MultiPartRequest类(源代码在下载使用)