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

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

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

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

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Java

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

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

解決済

1回答

10933閲覧

Javaサーブレット内のHttp通信Putメソッドでボディー部にKey/Valueパラメータを設定して渡す方法はありますか?

tutttwi

総合スコア20

HTTP

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

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Java

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

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

2グッド

2クリップ

投稿2016/07/09 08:50

PutメソッドのHTTP通信を使用してボディーにKey/Valueパラメータを渡す方法を探しています。

BodyにKey/Valueのパラメータを設定して、受け渡し先で

String value = request.get~("Key");

みたいな感じで取得できる様な渡し方ができたらと考えております。。

現在、下記方法でサーブレット内でHttp通信を実装しようとしておりますが、
Key/Valueで取得できる方法が見つからず、困っております。

【方法】

①ApacheのHttpClientクラス、PutMethodクラスを使用する方法
②HttpURLConnectionを使用する方法

【実装ソース】

①HttpClientクラス、PutMethodクラスを使用する方法

■送信側

lang

1 2public class HttpClientFrom extends HttpServlet { 3 4 @Override 5 public void doGet(HttpServletRequest req, HttpServletResponse resp) 6 throws ServletException, IOException { 7 8 System.out.println(this.getClass().toString() + "▼処理開始▼"); 9 10 URL url = new URL("http://localhost:8080/DymmyRenkei/HttpClientTo"); 11 12 HttpClient client = new HttpClient(); 13 PutMethod method = new PutMethod(url); 14 15 // String文字列として&区切りでボディに設定するが受信側でKey/Value形式で取得できない。。。 16 String entity = "test=bob&fruits=apples&hoge=こんにちは"; 17 RequestEntity et = new StringRequestEntity(entity, null, "UTF-8"); 18 19 method.setRequestEntity(entity); 20 21 // 複数文字列をKey, Value形式で設定するが受信側の取得方法が不明。。。 22 Part[] parts = { 23 new StringPart("hogePart","こんにちはパート"), 24 new StringPart("testPart","テスト文字列") 25 }; 26 method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams())); 27 28 int statusCode = client.excuteMethod(method); 29 System.out.println(statusCode); 30 System.out.println(this.getClass().toString() + "▲処理終了▲"); 31 } 32}

■受信側
※略:getInputStreamでBody部を読みこめば、
取得できることは確認できていますが、get~("Key")形式で取得する実装が実現できていない状況

②HttpURLConnectionを使用する方法

■送信側

lang

1public class ServletFrom extends HttpServlet { 2 3 @Override 4 public void doGet(HttpServletRequest req, HttpServletResponse resp) 5 throws ServletException, IOException { 6 7 System.out.println(this.getClass().toString() + "▼処理開始▼"); 8 9 URL url = new URL("http://localhost:8080/DymmyRenkei/To"); 10 11 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 12 con.setRequestMethod("PUT"); 13 con.setInstanceFollowRedirects(false); 14 con.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); 15 // setRequestPropertyでセットした値は送り先で取得できない... そもそも概念が違う? 16 con.setRequestProperty("key", "value"); 17 con.setDoOutput(true); 18 19 PrintStream ps = new PrintStream(con.getOutputStream()); 20 // ボディに" &区切りKey=Valued "で設定しても送り先でget系メソッドを使用して取得することはできない? 21 ps.print("test=bob&fruits=apples&hoge=こんにちは"); 22 23 con.connect(); 24 25 int st = con.getResponseCode(); 26 System.out.println(st); 27 28 System.out.println(this.getClass().toString() + "▲処理終了▲"); 29 30 31 32 } 33 34 35} 36

■受信側

lang

1 2public class ServletTo extends HttpServlet { 3 4 @Override 5 public void doPut(HttpServletRequest req, HttpServletResponse resp) 6 throws ServletException, IOException { 7 8 System.out.println(this.getClass().toString() + "▼処理開始▼"); 9 BufferedReader in; 10 in = new BufferedReader(new InputStreamReader(req.getInputStream())); 11 12 String line; 13 // Bodyに書き込んだ文字列がそのまま取れることは確認済み。加工しないとだめ? また、日本語がもじバケる現象 14 while((line = in.readLine()) != null){ 15 System.out.println(line); 16 } 17 18 in.close(); 19 20 // bodyに&区切りで入れたデータが取れるかと思ったが取れない... 21 System.out.println(req.getParameter("test")); 22 System.out.println(req.getParameter("fruits")); 23 System.out.println(req.getParameter("hoge")); 24 25 // setRequestPropertyで設定した値はこれでは取れない... 26 System.out.println(req.getParameter("key")); 27 28 29 resp.setStatus(200); 30 OutputStream out = resp.getOutputStream(); 31 out.write("★成功★".getBytes()); 32 33 34 35 System.out.println(this.getClass().toString() + "▲処理終了▲"); 36 37 } 38 39}

分かっていること

  • ヘッダー部であれば①、②の方法でKey/Valueで設定し取得できることを確認
  • HttpClientとPostMechodクラスであれば、addParameter("K","V")があるのでBody部にパラメータとして渡せること(putは無理なのかな)

質問内容

  1. Putメソッドでボディー部にKey/Valueパラメータを設定して渡す方法があるかどうか(Body部に一定の形式(JSON、区切り文字等)で送ることを受信先と認識合わせしないとダメ?)
  2. ①の実装で受信側で文字化けを起こさない様な送信側、受信側の実装方法が知りたい(Charsetにセットする文字列をあわせるとか?)
  3. ①、②の受信側の実装方法の具体例が知りたい(そもそも一般的に上記の様な実装であってるか不安。。)
  4. 本件、参考になるURLがあれば知りたい。(いろんなサイトを拝見したのですが該当せず、英語のAPIを眺めても解決に至りませんでした。。)

箇条書きでいくつもすみません。

上記ご教示の程宜しくお願い致します。

A-pZ, ikuwow👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

そうですね、ご明察です。
HttpServletのメソッドではBodyParameterは取得できず、あくまでサーブレット仕様で言うリクエストパラメータで認識できるパラメータしか getParameter() や getParameterValues() で取得できません。

なおHttpClientは現在4.5.2が最新ですので多少お使いのバージョンとは異なりますが、それでも送信側と受信側で文字コードと送信形式を合わせなければならないのは同じです。

文字化けの件については、HttpClientはBodyParameterに設定する際には、以下のコードのように対象文字列の文字コードを指定した上でURLエンコードした状態で送信できますので、受信側もURLDecodeで文字コードを指定して復元すれば文字化けは回避できるでしょう。

java

1package sample; 2 3import java.io.IOException; 4import java.util.ArrayList; 5import java.util.List; 6 7import javax.servlet.ServletException; 8import javax.servlet.annotation.WebServlet; 9import javax.servlet.http.HttpServlet; 10import javax.servlet.http.HttpServletRequest; 11import javax.servlet.http.HttpServletResponse; 12 13import org.apache.http.HttpEntity; 14import org.apache.http.NameValuePair; 15import org.apache.http.client.entity.UrlEncodedFormEntity; 16import org.apache.http.client.methods.CloseableHttpResponse; 17import org.apache.http.client.methods.HttpPut; 18import org.apache.http.impl.client.CloseableHttpClient; 19import org.apache.http.impl.client.HttpClients; 20import org.apache.http.message.BasicNameValuePair; 21import org.apache.http.util.EntityUtils; 22 23/** 24 * Servlet implementation class FromServlet 25 */ 26@WebServlet("/FromServlet") 27public class FromServlet extends HttpServlet { 28 private static final long serialVersionUID = 1L; 29 30 /** 31 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 32 */ 33 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 34 CloseableHttpClient httpclient = HttpClients.createDefault(); 35 HttpPut put = new HttpPut("http://127.0.0.1:8080/Chaining/ToServlet"); 36 37 List<NameValuePair> nameValuePair = new ArrayList<>(); 38 nameValuePair.add(new BasicNameValuePair("username", "カピバラ")); 39 nameValuePair.add(new BasicNameValuePair("address", "パンタナール一丁目")); 40 41 put.setEntity(new UrlEncodedFormEntity(nameValuePair,"utf-8")); 42 43 CloseableHttpResponse httpresponse = httpclient.execute(put); 44 45 HttpEntity entity = httpresponse.getEntity(); 46 EntityUtils.consume(entity); 47 48 httpresponse.close(); 49 } 50}

java

1package sample; 2 3import java.io.BufferedReader; 4import java.io.IOException; 5import java.io.InputStreamReader; 6import java.io.PrintWriter; 7import java.net.URLDecoder; 8import java.nio.charset.Charset; 9import java.util.List; 10import java.util.Map; 11 12import javax.servlet.ServletException; 13import javax.servlet.annotation.WebServlet; 14import javax.servlet.http.HttpServlet; 15import javax.servlet.http.HttpServletRequest; 16import javax.servlet.http.HttpServletResponse; 17 18import org.apache.http.NameValuePair; 19import org.apache.http.client.utils.URLEncodedUtils; 20 21/** 22 * Servlet implementation class ToServlet 23 */ 24@WebServlet("/ToServlet") 25public class ToServlet extends HttpServlet { 26 private static final long serialVersionUID = 1L; 27 28 /** 29 * @see HttpServlet#doPut(HttpServletRequest, HttpServletResponse) 30 */ 31 protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 32 log("encoding:" + request.getCharacterEncoding()); 33 34 Map<String,String[]> parameterMaps = request.getParameterMap(); 35 parameterMaps.entrySet().stream().forEach(entry -> { 36 log("key :" + entry.getKey() + "=" + entry.getValue()); 37 }); 38 39 BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream())); 40 String line; 41 while((line = in.readLine()) != null){ 42 // RequestBody 43 log(line); 44 45 // URLデコードした内容 46 log(URLDecoder.decode(line, "utf-8")); 47 48 // Commons HttpClientのユーティリティで解析 49 List<NameValuePair> nameValuePair = URLEncodedUtils.parse(line, Charset.forName("utf-8")); 50 51 nameValuePair.stream().forEach(pair -> { 52 log("paremeter: " + pair.getName() + " = " + pair.getValue()); 53 }); 54 } 55 in.close(); 56 57 response.setHeader("responseKey", "received."); 58 response.setCharacterEncoding("utf-8"); 59 PrintWriter out = response.getWriter(); 60 out.append("完了しました"); 61 62 out.flush(); 63 out.close(); 64 } 65}

実行結果:

情報: sample.ToServlet: encoding:UTF-8 [土 7 09 23:33:53 JST 2016] 情報: sample.ToServlet: username=%E3%82%AB%E3%83%94%E3%83%90%E3%83%A9&address=%E3%83%91%E3%83%B3%E3%82%BF%E3%83%8A%E3%83%BC%E3%83%AB%E4%B8%80%E4%B8%81%E7%9B%AE [土 7 09 23:33:53 JST 2016] 情報: sample.ToServlet: username=カピバラ&address=パンタナール一丁目 [土 7 09 23:33:53 JST 2016] 情報: sample.ToServlet: paremeter: username = カピバラ [土 7 09 23:33:53 JST 2016] 情報: sample.ToServlet: paremeter: address = パンタナール一丁目 [土 7 09 23:33:53 JST 2016]

投稿2016/07/09 14:35

A-pZ

総合スコア12011

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

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

tutttwi

2016/07/10 08:57

ご回答ありがとう御座います。 そうですよね。。 サンプルのご提供ありがとう御座います。! >HttpServletのメソッドではBodyParameterは取得できない >エンコード指定は送受信で合わせる必要がある 実行環境の記載ができておらず申し訳ございません、、 開発環境として、 ・Java1.5 ・commons-httpclient-3.1.jar ・etc.. で開発しておりますので、Commons時代のhttpclientしか使用できないような状況です。 (Value部だけエンコードしてくれる便利なUtilもなく、不便です。。 これだったらHttpURLConnectionでいいのかなと感じてます) ですので、①、②どちらかの方法でボディ部に ---Body key01=%Value02%&key02&%Value02%&... --- %~% はURLEncodeしている状態 の様な形で実装しようかなと思っております* ありがとうございます。 【commons-httpclient-3.1.jar】バージョンで実装 https://github.com/tutttuwi/MyCat 【参照API】 https://hc.apache.org/httpclient-3.x/apidocs/overview-summary.html
A-pZ

2016/07/11 01:43

d(・ω・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問