2013-09-28 30 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它,你是好!