質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

TERASOLUNA

TERASOLUNA(テラソルナ)はNTTデータの独自フレームワークです。 比較的大規模なシステム開発における 開発手順・フレームワーク・サポートなどの製品群により構成されています。

Q&A

解決済

1回答

816閲覧

httpリクエスト発行時の411エラーの解消

smc96631

総合スコア1

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

HttpWebRequest

HttpWebRequestとは.NETにおけるクラスであり、WebRequestクラスをHTTPに導入するものです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

TERASOLUNA

TERASOLUNA(テラソルナ)はNTTデータの独自フレームワークです。 比較的大規模なシステム開発における 開発手順・フレームワーク・サポートなどの製品群により構成されています。

0グッド

0クリップ

投稿2023/09/07 12:28

編集2023/09/07 12:40

実現したいこと

  • HttpURLConnectionオブジェクトを使用してhttpリクエストを発行し、APIを実行したい

前提

組織内のみで利用しているwebシステムからhttpリクエストを発行し、
インターネット上の配置されているAPIを実行する機能を作成しています。
httpリクエストを発行する処理で、レスポンスコード:411(Length Required)が発生しています。

発生している問題・エラーメッセージ

レスポンスを確認しているコード int statusCode = con.getResponseCode(); if (statusCode == con.HTTP_OK) { system.out.println("success"); system.out.println("STATUS:" + statusCode); system.out.println("MSG:" + con.getResponseMessage()); } else { system.out.println("fault"); system.out.println("STATUS:" + statusCode); system.out.println("MSG:" + con.getResponseMessage()); } コンソール表示 fault STATUS:411 MSG:Length Required

該当のソースコード

Java8

1ソースコード 2 try { 3 // URL作成 4 URL url = new URL("https://hogehoge/post?SYSTEM_ID=" + systemID); 5 // 接続用HttpURLConnectionオブジェクト作成 6 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 7 // リクエストメソッドの設定 8 con.setRequestMethod("POST"); 9 // リクエストのボディ送信を許可 10 con.setDoOutput(true); 11 // リクエストのボディ受信を許可 12 con.setDoInput(true); 13 // ヘッダーの設定 14 con.setRequestProperty("APIKEY", "APIの認証キー"); 15 con.setRequestProperty("Content-Type", "application/json;charset=utf-8"); 16 17 // 接続 18 con.connect(); 19 20 //レスポンス確認 21 int statusCode = con.getResponseCode(); 22 if (statusCode == con.HTTP_OK) { 23 system.out.println("success"); 24 system.out.println("STATUS:" + statusCode); 25 system.out.println("MSG:" + con.getResponseMessage()); 26 } else { 27 system.out.println("fault"); 28 system.out.println("STATUS:" + statusCode); 29 system.out.println("MSG:" + con.getResponseMessage()); 30 } 31 32 con.disconnect(); 33 34 } catch (IOException e) { 35 system.out.println("NG"); 36 // TODO 自動生成された catch ブロック 37 e.printStackTrace(); 38 }

試したこと

レスポンスコード:411は、[Content-Length]の不備が原因とのことだったため、
以下のコード追加して動作検証しました。
結果としてはレスポンス確認している[int statusCode = con.getResponseCode();]の箇所で
エラーが発生するようになり、レスポンス確認すらできない状態になりました。
また、con.getContentLength()のコマンドで設定内容を確認すると常に"-1"が返却され、
con.getRequestProperty("content-length")で設定内容を確認すると設定した値が返却されます。

以下のコードを[con.connect();]の前に追加。

System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); // content-lengthの設定 byte[] data = ("https://hogehoge/post?SYSTEM_ID=" + systemID).getBytes("UTF-8"); con.setRequestProperty("content-length", String.valueOf(data.length));

※HttpURLConnectionでは、[content-length]を設定しても↑の1行目の設定をしないと暗黙的に削除してしまうとの情報があったため追加

補足情報(FW/ツールのバージョンなど)

・APサーバ:Linux
(httpリクエストが通るように対象URLのIPアドレスは許可している)
・フレームワーク:Terasoluna
・使用オブジェクト:HttpURLConnection
(Java8環境で使用できるオブジェクトがこれしか見つからなかったため)

本処理実装に取り掛かってから、3日間調査していますが、解決策が見つかりません。
どうかご協力のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2023/09/07 15:18 編集

相手が「送ってくるデータがおかしい」と言ってきているのですから、 API に送るデータがどうなっていなければならないのか(仕様)、そして実際には何を送っているのかを確認するしかないのでは。 赤の他人にはそれらが分からない以上、どうしようも無いと思います。 (ヘッダだけ送ってボディは何も無さそうですし)
smc96631

2023/09/07 23:40

コメントありがとうございます。 API側の仕様としては、  ・"POST"メソッドのよるリクエスト  ・ヘッダー部に"APIKEY"で認証キーを設定  ・URLにAPI側の処理に必要なパラメータを設定 を確認しており、ボディについては特に指定がありません。
jimbe

2023/09/08 00:24

ボディが要らないなら // リクエストのボディ送信を許可 con.setDoOutput(true); は不要では。
smc96631

2023/09/08 01:22

// リクエストのボディ送信を許可 con.setDoOutput(true); この設定をデフォルト値(false)で実行してみましたが、411エラーの発生状況は変わりませんでした。 また、原因調査中ですが「試したこと」の対応を適用しても"content-length"に値が設定できない状態になりました。
jimbe

2023/09/08 03:39

ダメでしたか・・・お手数お掛けしてすいません。 ローカルなサーバなりローカルループバックなりを利用して、実際にどのようなhttp要求が API のサーバに送られているのかを確認しては如何でしょう。
smc96631

2023/09/08 05:42

実行環境に依る問題か、コード上の問題かはっきりしなかったため、  ローカルサーバ環境でコードの問題に絞って調査したところ解決しました。 コメントありがとうございました。
guest

回答1

0

自己解決

解決しましたので、変更前、変更後のコードを書いておきます。
また、仕様変更としてURLに埋め込んでいたパラメータをヘッダー部に移動しています

【変更前】
con.connect();

【変更後】
OutputStream os = con.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));

writer.flush();
writer.close();
os.close();

パラメータのみを渡して、データ書き込みを行うようなAPIではなかったため、
OutputStreamは使用しないという思い込みがありました。

ご協力いただきありがとうございました。

投稿2023/09/08 05:33

smc96631

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問