0

ポート 6799 で Java Web サーバーを実行しています。ディレクトリには txt.txt ファイルと pdf.pdf ファイルがあります。localhost:6799/txt.txt を指定すると、完璧な出力が得られます。

GET /txt.txt HTTP/1.1HTTP/1.0 200 OK コンテンツ タイプ: テキスト/プレーン

これは非常に単純なテキスト ファイルです。

しかし、ブラウザから 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";
    }
}

スタックトレース

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)
4

2 に答える 2

0

少なくとも 1 つの問題は次のコードです。

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

BufferedReadernullはストリームの最後に戻るため.length()、null オブジェクトを呼び出すとNullPointerException.

これを書くためのより慣用的な方法は次のとおりです。

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

(headerLine = br.readLine())... の結果がisの場合、短絡論理を利用して 2 番目の条件を評価しませんnull

于 2013-09-28T20:25:52.420 に答える
0

何らかの理由で、次の行でコメントを切り替えたために発生しています。

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

それをオフにすると、あなたはいいです!

于 2013-09-30T06:53:45.007 に答える