Apache Ant Get
task を使用して、社内の他のチームが生成したWSDLのリストを取得しようとしました。 http://....com:7925/services / のweblogic 9.xサーバーでホストされています。ブラウザーからページにアクセスできますが、ページをローカルファイルにコピーして解析しようとすると、getタスクでFileNotFoundExceptionが発生します。 (antタスクを使用して)HTTPの非標準ポート80がなくてもURLを取得できました。
Antのソースコードを調べ、エラーをURLConnectionに絞り込みました。プロトコルがHTTPとして指定されていても、URLConnectionは標準ポート上にないため、データがHTTPトラフィックであることを認識しないようです。 WireSharkを使用してトラフィックをスニッフィングし、ページがネットワーク全体で正しくロードされましたが、それでもFileNotFoundExceptionが発生します。
エラーが表示される例を次に示します(無実を保護するためにURLが変更されています)。エラーはconnection.getInputStream();でスローされます
import Java.io.File;
import Java.io.InputStream;
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", "test.com", 7925,
"/services/index.html");
URLConnection connection = source.openConnection();
connection.connect();
InputStream is = connection.getInputStream();
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
サーバーから返される応答コードを確認します
HTTPリクエストへの応答がステータスコード404で返され、getInputStream()を呼び出したときにFileNotFoundExceptionが発生しました。それでも応答の本文を読みたいので、別のメソッドHttpURLConnection#getErrorStream()を使用する必要がありました。
GetErrorStream()のJavaDocスニペットは次のとおりです。
接続が失敗してもサーバーが有用なデータを送信した場合は、エラーストリームを返します。典型的な例は、HTTPサーバーが404で応答する場合です。これにより、FileNotFoundExceptionが接続でスローされますが、サーバーは、何をすべきかについての提案を含むHTMLヘルプページを送信しました。
使用例:
public static String httpGet(String url) {
HttpURLConnection con = null;
InputStream is = null;
try {
con = (HttpURLConnection) new URL(url).openConnection();
con.connect();
//4xx: client error, 5xx: server error. See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
boolean isError = con.getResponseCode() >= 400;
//In HTTP error cases, HttpURLConnection only gives you the input stream via #getErrorStream().
is = isError ? con.getErrorStream() : con.getInputStream();
String contentEncoding = con.getContentEncoding() != null ? con.getContentEncoding() : "UTF-8";
return IOUtils.toString(is, contentEncoding); //Apache Commons IO
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
//Note: Closing the InputStream manually may be unnecessary, depending on the implementation of HttpURLConnection#disconnect(). Sun/Oracle's implementation does close it for you in said method.
if (is != null) {
try {
is.close();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
if (con != null) {
con.disconnect();
}
}
}
これは古いスレッドですが、同様の問題があり、ここに記載されていない解決策を見つけました。
ブラウザでページを正常に受信していましたが、HttpURLConnectionを介してアクセスしようとしたときに404を取得しました。アクセスしようとしたURLにポート番号が含まれていました。ポート番号なしで試したところ、HttpURLConnectionを介してダミーページを取得できました。したがって、非標準ポートが問題であるように思われました。
私はアクセスが制限されていると思い始めました、そしてある意味それはそうでした。私の解決策は、サーバーにユーザーエージェントを通知する必要があり、予想されるファイルの種類も指定することでした。私は.jsonファイルを読み取ろうとしているので、ファイルタイプも必要な仕様であると思いました。
私はこれらの行を追加し、それが最終的に機能しました:
httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
私はこれが古いスレッドであることを知っていますが、ここにリストされていない解決策を見つけました。
ポート8080のJ2EEサーブレットからjson形式のデータをプルしようとしましたが、ファイルが見つからないというエラーを受け取りました。ポート80で実行されているphpサーバーから同じjsonデータをプルすることができました。
サーブレットでは、doGetをdoPostに変更する必要があることがわかりました。
これが誰かを助けることを願っています。
OkHttp を使用できます:
OkHttpClient client = new OkHttpClient(); String run(String url) throws IOException { Request request = new Request.Builder() .url(url) .build(); Response response = client.newCall(request).execute(); return response.body().string(); }
私はこれが古いスレッドであることを知っていますが、このスレッドで何かに気付いたので、それをそのままにしようと思いました。
Jessicaが述べたように、この例外は非標準のポートを使用している場合にスローされます。
DNSを使用している場合にのみ発生するようです。 IP番号を使用すると、ポート番号を指定でき、すべて正常に動作します。
提供されたコードを使用して、ローカルでそれを試しましたが、サーバーがステータス404応答を返す場合を除いて、FileNotFoundException
を取得できません。
接続する予定のWebサーバーに接続していますか?別のウェブサーバーに接続している可能性はありますか? (コードのポート番号がリンクのポート番号と一致しないことに注意してください)
私は同様の問題に遭遇しましたが、理由は異なっているようです、ここに例外トレースがあります:
Java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
at Sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
at Sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.Java:27)
at Java.lang.reflect.Constructor.newInstance(Constructor.Java:513)
at Sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.Java:1491)
at Java.security.AccessController.doPrivileged(Native Method)
at Sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.Java:1485)
at Sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:1139)
at com.doitnext.loadmonger.HttpExecution.getBody(HttpExecution.Java:85)
at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.Java:214)
at com.doitnext.loadmonger.ClientWorker.run(ClientWorker.Java:126)
at Java.lang.Thread.run(Thread.Java:680)
Caused by: Java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
at Sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:1434)
at Java.net.HttpURLConnection.getResponseCode(HttpURLConnection.Java:379)
at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.Java:166)
... 2 more
そのため、応答コードを取得するだけで、URL接続がGetInputStreamを呼び出すようになるようです。