简体   繁体   English

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

[英]JAVA pdf response error in implementing http 1 socket programming

I run my java webserver on port 6799 My directory has a txt.txt file and pdf.pdf file When I give localhost:6799/txt.txt, it gives perfect output saying 我在端口6799上运行Java Web服务器。我的目录中有txt.txt文件和pdf.pdf文件。当我输入localhost:6799 / txt.txt时,它会给出完美的输出说

GET /txt.txt HTTP/1.1HTTP/1.0 200 OK Content-type: text/plain GET /txt.txt HTTP / 1.1HTTP / 1.0 200 OK内容类型:文本/纯文本

This is a very simple text file 这是一个非常简单的文本文件

But when I give localhost:6799/pdf.pdf from browser, it gives java.lang.NullPointerException 但是当我从浏览器提供localhost:6799 / pdf.pdf时,它给出了java.lang.NullPointerException

This is my code 这是我的代码

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)

At least one issue is this code: 至少一个问题是此代码:

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

BufferedReader will return null at the end of the stream, so calling .length() on a null object will yield a NullPointerException . BufferedReader将在流的末尾返回null ,因此在null对象上调用.length()将产生NullPointerException

A more idiomatic way to write this is: 一种更惯用的写法是:

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

...which takes advantage of short-circuit logic to not evaluate the second condition if the result of (headerLine = br.readLine()) is null . ...如果(headerLine = br.readLine())null ,则利用短路逻辑不评估第二个条件。

It is happening because for some reason you have toggled comment on the following line: 发生这种情况是因为出于某种原因,您在以下行上切换了注释:

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

Untoggle it and you're good! 取消切换,您就很好了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM