简体   繁体   English

可以使用浏览器访问URL,但使用URLConnection仍可以访问FileNotFoundException

[英]URL is accessable with browser but still FileNotFoundException with URLConnection

I use a HttpURLConnection to connect to a website and receive an ResponseCode=404 (HTTP_NOT_FOUND). 我使用HttpURLConnection连接到网站并收到ResponseCode = 404(HTTP_NOT_FOUND)。 However I have no problem opening the website in my browser (IE). 但是,我在浏览器(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$6.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/

You are getting 404 error that means the response for the request is not found. 您收到404错误,这意味着找不到请求的响应。 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. 首先,您需要确保在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. 测试url是否有任何内容的最简单方法是将url粘贴到Web浏览器的地址栏上,然后单击go。 However, this does not guarantee that the Java code will be able to access it. 但是,这不能保证Java代码将能够访问它。 For example, if the server is designed to response 404 if it cannot find the web browser User-Agent header. 例如,如果服务器被设计为在找不到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. 根据您最新版本的问题,您可以使用网络浏览器查看该问题,但无法使用您的Java代码下载该文件,并且标题似乎设置正确。 There are only two problem I can see: 我只能看到两个问题:

  1. You should not set connection.setDoOutput(true); 您不应该设置connection.setDoOutput(true); to true. 真实。 This will enforce the connection to do HTTP POST instead of GET and the server may not support POST. 这将强制连接执行HTTP POST而不是GET,并且服务器可能不支持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. 您的服务器即使总是应该返回200,也可能始终返回404。由于Web浏览器不关心错误状态,而是尝试呈现所有内容,因此似乎可以从Web浏览器正常工作。 If so, you should fix the server to reponse correctly first, otherwise try getting error stream instead HttpURLConnection#getErrorStream() 如果是这样,则应该修复服务器以首先正确响应,否则尝试获取错误流,而不是HttpURLConnection#getErrorStream()

I had a similar issue. 我有一个类似的问题。 For me it helped to inspect the packets using RawCap . 对我来说,它有助于使用RawCap检查数据包。 RawCap is one of the few Windows packet sniffers that lets you sniff localhost. RawCap是可让您嗅探本地主机的少数Windows数据包嗅探器之一。

In my cases the server was returning a 404 due to an authentication issue. 在我的情况下,由于身份验证问题,服务器返回了404。

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. 就我而言,实际上我在同一端口上运行了另一个进程,该进程正在窃取Java应用程序的请求。 Using yair's answer here you can check for a process running on the same port like this: In the command prompt, do netstat -nao | find "8080" 在这里使用yair的答案您可以像这样检查在同一端口上运行的进程:在命令提示符下,执行netstat -nao | find "8080" netstat -nao | find "8080" on Windows or netstat -nap | grep 8080 在Windows或netstat -nap | grep 8080netstat -nao | find "8080" netstat -nap | grep 8080 netstat -nap | grep 8080 on Linux. Linux上的netstat -nap | grep 8080 It should show a line with LISTENING and 127.0.0.1:8080 and next would be the process ID. 它应该显示带有LISTENING和127.0.0.1:8080的行,然后是进程ID。 Just terminate the process and you should be good to go. 只需终止该过程,您就应该做好了。

I had the problem too. 我也有问题。 In my case i had a invisible unicode character in the url string. 就我而言,URL字符串中有一个不可见的Unicode字符。 So connection couldnt open it (FileNotFound indicates that). 因此,连接无法打开它(FileNotFound指示)。 I removed it and it worked. 我删除了它,它起作用了。

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. 我有一个类似的场景,其中Web服务正确处理了来自浏览器的POST请求(在我的案例中为Postman,它是一个测试Chrome扩展程序的API),但是HttpURLConnection对于大型有效负载始终失败,并带有404错误。 I mistakenly assumed that the problem must be in my HttpURLConnection client code. 我错误地认为问题必须出在我的HttpURLConnection客户端代码中。

When I later tried to replicate the request from cUrl with a large payload, I got the same 404 error. 后来,当我尝试使用较大的有效负载从cUrl复制请求时,出现了相同的404错误。 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. 即使我使用了Postman生成的cUrl代码,因此它应该与Postman的请求相同,但是Web服务对两个请求的反应方式还是有所不同。 Some client middleware on Postman may have intercepted and modified the requests. Postman上的某些客户端中间件可能已经拦截并修改了请求。

TL;DR TL; DR

Check the web service. 检查Web服务。 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服务如何对此作出反应。

If the url http://localhost:8080/ can be accessed well in the web browser, the code should work well. 如果可以在Web浏览器中很好地访问URL http:// localhost:8080 / ,则代码应该可以正常工作。 I run the program in my machine, it works well. 我在机器上运行该程序,它运行良好。 So you must check whether the webserver service is ok. 因此,您必须检查Web服务器服务是否正常。

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

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