Java URL 可通过浏览器访问,但仍使用 URLConnection 进行 FileNotFoundException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8279219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-15 00:36:01  来源:igfitidea点击:

URL is accessable with browser but still FileNotFoundException with URLConnection

java

提问by Pavan Kumar

I use a HttpURLConnection to connect to a website and receive an ResponseCode=404 (HTTP_NOT_FOUND). However I have no problem opening the website in my browser (IE).

我使用 HttpURLConnection 连接到网站并收到 ResponseCode=404 (HTTP_NOT_FOUND)。但是,我在浏览器(IE)中打开网站没有问题。

Why the difference, and what can I do about it?

为什么会有所不同,我该怎么办?

Regards, Pavan

问候, 帕万

This is my Program

这是我的程序

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

public class TestGet {
    private static URL source;

    public static void main(String[] args) {
        doGet();
    }

    public static void doGet() {
        try {
            source = new URL("http://localhost:8080/");

            System.out.println("Url is" + source.toString());

            URLConnection connection = source.openConnection();
            connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
            connection.setRequestProperty("Accept","*/*");
            connection.setDoInput(true);
            connection.setDoOutput(true);

            System.out.println(((HttpURLConnection) connection).getResponseCode());
            BufferedReader rdr = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            StringBuffer b = new StringBuffer();
            String line = null;
            while (true) {
                line = rdr.readLine();
                if (line == null)
                    break;
                b.append(line);
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.toString());
        }
    }

}

Stack Trace

堆栈跟踪

Url ishttp://localhost:8080/
404
java.io.FileNotFoundException: http://localhost:8080/
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at TestGet.doGet(TestGet.java:28)
    at TestGet.main(TestGet.java:11)
Caused by: java.io.FileNotFoundException: http://localhost:8080/
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at TestGet.doGet(TestGet.java:26)
    ... 1 more
java.io.FileNotFoundException: http://localhost:8080/

回答by Andy Jiang

If the url http://localhost:8080/can be accessed well in the web browser, the code should work well. I run the program in my machine, it works well. So you must check whether the webserver service is ok.

如果 url http://localhost:8080/可以在 Web 浏览器中正常访问,则代码应该可以正常工作。我在我的机器上运行该程序,它运行良好。所以你必须检查webserver服务是否正常。

回答by gigadot

You are getting 404 error that means the response for the request is not found. First you need to make sure that there is a server serving at http://localhost:8080/and it must return some content with code 200. If not, then there is nothing we can help you.

您收到 404 错误,这意味着找不到请求的响应。首先,您需要确保有一个服务器在提供服务,http://localhost:8080/并且它必须返回一些代码为 200 的内容。如果没有,那么我们无法为您提供帮助。

The easiest way to test whether there is anything at the url is to paste the url on the web browser address bar and click go. However, this does not guarantee that the Java code will be able to access it. For example, if the server is designed to response 404 if it cannot find the web browser User-Agentheader.

测试 url 是否有任何内容的最简单方法是将 url 粘贴到 Web 浏览器地址栏上,然后单击 go。但是,这并不能保证 Java 代码能够访问它。例如,如果服务器设计为在找不到 Web 浏览器User-Agent标头时响应 404 。

Since the server returns a status code, either 200 or 404, it means this is not a firewall problem.

由于服务器返回状态代码,无论是 200 还是 404,这意味着这不是防火墙问题。

According to your latest edition of the question, you can view it with the web browser but cannot download it with your java code and the header seems to be set correctly. There are only two problem I can see:

根据您最新版本的问题,您可以使用网络浏览器查看它,但无法使用您的 java 代码下载它,并且标题似乎设置正确。我只能看到两个问题:

  1. You should not set connection.setDoOutput(true);to true. This will enforce the connection to do HTTP POST instead of GET and the server may not support POST.

  2. Your server may be always returning 404 even if it should have been 200. Since the web browser doesn't care about the error status and tries to render all the content so it seems to be working from the web browser. If so, you should fix the server to reponse correctly first, otherwise try getting error stream instead HttpURLConnection#getErrorStream()

  1. 你不应该设置connection.setDoOutput(true);为 true。这将强制连接执行 HTTP POST 而不是 GET,并且服务器可能不支持 POST。

  2. 您的服务器可能总是返回 404,即使它应该是 200。由于 Web 浏览器不关心错误状态并尝试呈现所有内容,因此它似乎可以从 Web 浏览器工作。如果是这样,您应该首先修复服务器以正确响应,否则尝试获取错误流HttpURLConnection#getErrorStream()

回答by jlars62

I know this is very late in the game, but I was just recently having the same issue and none of the solutions here worked for me. In my case, I actually had another process running on the same port that was stealing the requests from the java app. Using yair's answer hereyou can check for a process running on the same port like this: In the command prompt, do netstat -nao | find "8080"on Windows or netstat -nap | grep 8080on Linux. It should show a line with LISTENING and 127.0.0.1:8080 and next would be the process ID. Just terminate the process and you should be good to go.

我知道这在游戏中已经很晚了,但我最近遇到了同样的问题,这里没有一个解决方案对我有用。就我而言,我实际上在同一个端口上运行了另一个进程,该进程正在窃取来自 Java 应用程序的请求。在这里使用 yair 的回答您可以像这样检查在同一端口上运行的进程:在命令提示符下,netstat -nao | find "8080"在 Windows 或netstat -nap | grep 8080Linux 上执行。它应该显示一行,其中包含 LISTENING 和 127.0.0.1:8080,接下来是进程 ID。只需终止该过程,您就可以开始了。

回答by Iain

I had a similar issue. For me it helped to inspect the packets using RawCap. RawCap is one of the few Windows packet sniffers that lets you sniff localhost.

我有一个类似的问题。对我来说,它有助于使用RawCap检查数据包。RawCap 是少数可让您嗅探本地主机的 Windows 数据包嗅探器之一。

In my cases the server was returning a 404 due to an authentication issue.

在我的情况下,由于身份验证问题,服务器返回 404。

回答by Amarbat

I had the problem too. In my case i had a invisible unicode character in the url string. So connection couldnt open it (FileNotFound indicates that). I removed it and it worked.

我也有这个问题。就我而言,我在 url 字符串中有一个不可见的 unicode 字符。所以连接无法打开它(FileNotFound 表明)。我删除了它并且它起作用了。

回答by Protongun

I had a similar scenario where the web service processed POST requests from the browser (in my case Postman, an API testing Chrome extension) correctly, but HttpURLConnection kept failing with a 404 for large payloads. I mistakenly assumed that the problem must be in my HttpURLConnection client code.

我有一个类似的场景,Web 服务正确地处理了来自浏览器的 POST 请求(在我的例子中是 Postman,一个 API 测试 Chrome 扩展),但 HttpURLConnection 一直失败,对于大负载的 404。我错误地认为问题一定出在我的 HttpURLConnection 客户端代码中。

When I later tried to replicate the request from cUrl with a large payload, I got the same 404 error. Even though I used the cUrl code generated by Postman, which therefore should be identical to Postman's request, there was a difference in how the web service reacted to both requests. Some client middleware on Postman may have intercepted and modified the requests.

当我后来尝试使用大负载复制来自 cUrl 的请求时,我遇到了相同的 404 错误。尽管我使用了 Postman 生成的 cUrl 代码,因此它应该与 Postman 的请求相同,但 Web 服务对这两个请求的反应方式有所不同。Postman 上的一些客户端中间件可能已经拦截并修改了请求。

TL;DR

TL; 博士

Check the web service. It may be the culprit. Try another non-browser barebones Http client like cUrl to see how the web service reacts to it.

检查网络服务。它可能是罪魁祸首。尝试另一个非浏览器准系统 Http 客户端,如 cUrl,以查看 Web 服务如何对其做出反应。