实现http 1套接字编程时JAVA pdf响应错误

时间:2013-09-28 20:20:59

标签: java sockets http pdf network-programming

我在端口6799上运行我的java webserver 我的目录有一个txt.txt文件和pdf.pdf文件 当我给localhost:6799 / txt.txt时,它提供了完美的输出

GET /txt.txt HTTP / 1.1HTTP / 1.0 200 OK 内容类型:text / plain

这是一个非常简单的文本文件

但是当我从浏览器给出localhost: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";
    }
}

STACK TRACE

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 :(得分: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,则利用短路逻辑不评估第二个条件。

答案 1 :(得分:0)

这种情况正在发生,因为出于某种原因,您已在以下一行切换评论:

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

解开它,你很好!