2013-09-28 29 views
0

我在端口6799上運行我的java web服務器 我的目錄有一個txt.txt文件和pdf.pdf文件 當我給localhost:6799/txt.txt時,輸出話說執行http 1套接字編程的JAVA pdf響應錯誤

GET /txt.txt HTTP/1.1HTTP/1.0 200 OK 內容類型:text/plain的

這是一個非常簡單的文本文件

但是,當我給本地主機:6799 /來自瀏覽器的pdf.pdf,它給出java.lang.NullPointerException

這是我的代碼

import java.net.*; 

public final class WebServer { 

    public static void main(String args[]) throws Exception { 
     int port = 6799; 
     System.out.println("\nListening on port " + port); 
     ServerSocket listen = new ServerSocket(port); 
     while (true) { 
      Socket socket = listen.accept(); 
      HttpRequest request = new HttpRequest(socket); 
      Thread thread = new Thread(request); 
      thread.start(); 
     } 
    } 
} 

-

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

public final class HttpRequest implements Runnable { 

    final String CRLF = "\r\n"; 
    Socket socket; 

    public HttpRequest(Socket socket) throws Exception { 
     this.socket = socket; 
    } 

    @Override 
    public void run() { 
     try { 
      processRequest(); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

    private void processRequest() throws Exception { 
     BufferedReader br; 
     DataOutputStream dos; 
     try (InputStream is = socket.getInputStream()) { 
      br = new BufferedReader(new InputStreamReader(is)); 
      String requestline = br.readLine(); 
      System.out.println("\n" + requestline); 
      String headerLine = null; 
      while ((headerLine = br.readLine()).length() != 0) { 
       System.out.println(headerLine); 
      } 
      dos = new DataOutputStream(socket.getOutputStream()); 
      dos.writeBytes(requestline); 
      StringTokenizer tokens = new StringTokenizer(requestline); 
      tokens.nextToken(); // skip over the method, which should be "GET" 
      String fileName = tokens.nextToken(); 
      // Prepend a "." so that file request is within the current directory. 
      fileName = "." + fileName; 
      FileInputStream fis = null; 
      boolean fileExists = true; 
      try { 
       fis = new FileInputStream(fileName); 
      } catch (FileNotFoundException e) { 
       fileExists = false; 
      } 
      String statusLine = null; 
      String contentTypeLine = null; 
      String entityBody = null; 
      if (fileExists) { 
       statusLine = "HTTP/1.0 200 OK" + CRLF; 
       contentTypeLine = "Content-type: " + contentType(fileName) + CRLF; 
      } else { 
       statusLine = "HTTP/1.0 404 Not Found" + CRLF; 
       //contentTypeLine = "Content-type: " + "text/html" + CRLF; 
       entityBody = "<HTML>" 
         + "<HEAD><TITLE>Not Found</TITLE></HEAD>" 
         + "<BODY>Not Found</BODY></HTML>"; 
      } 
      dos.writeBytes(statusLine); 
      dos.writeBytes(contentTypeLine); 
      dos.writeBytes(CRLF); 
      if (fileExists) { 
       sendBytes(fis, dos); 
       fis.close(); 
      } else { 
       dos.writeBytes(entityBody); 
      } 

     } 
     br.close(); 
     dos.close(); 
     socket.close(); 
    } 

    private void sendBytes(FileInputStream fis, DataOutputStream dos) throws IOException { 
     byte[] buffer = new byte[4096]; 
     int bytes = 0; 
     while ((bytes = fis.read(buffer)) != -1) { 
      dos.write(buffer, 0, bytes); 
     } 
    } 

    private String contentType(String fileName) { 
     if (fileName.endsWith(".htm") || fileName.endsWith(".html")) { 
      return "text/html"; 
     } 
     if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { 
      return "image/jpeg"; 
     } 
     if (fileName.endsWith(".gif")) { 
      return "image/gif"; 
     } 
     if (fileName.endsWith(".txt")) { 
      return "text/plain"; 
     } 
     if (fileName.endsWith(".pdf")) { 
      return "application/pdf"; 
     } 
     return "application/octet-stream"; 
    } 
} 

堆棧跟蹤

java.lang.NullPointerException 
at java.io.DataOutputStream.writeBytes(DataOutputStream.java:274) 
at HttpRequest.processRequest(HttpRequest.java:65) 
at HttpRequest.run(HttpRequest.java:20) 
at java.lang.Thread.run(Thread.java:724) 
+2

如何使用行號提供整個堆棧跟蹤? –

+0

你有'contentTypeLine =「Content-type:」+「text/html」+ CRLF;'註釋掉了,但之後仍然使用它。 – mkl

回答

0

至少有一個問題是這樣的代碼:

while ((headerLine = br.readLine()).length() != 0) { 
    System.out.println(headerLine); 
} 

BufferedReader將返回流末尾的null,因此在空對象上調用.length()將產生NullPointerException

更慣用的方式來寫是這樣的:

while ((headerLine = br.readLine()) != null && headerLine.length() != 0) { 
    System.out.println(headerLine); 
} 

...這需要短路邏輯的優勢,如果的(headerLine = br.readLine())結果null不評估第二條件。

+0

其在線 中的錯誤錯誤dos.writeBytes(contentTypeLine); – Hardik

+0

@Hardik:那麼contentTypeLine就是null。 –

0

這是因爲發生了某種原因,你已經切換到下一行註釋:

//contentTypeLine = "Content-type: " + "text/html" + CRLF; 

Untoggle它,你是好!