概要
JavaでJSONをHTTP POSTしたりHTTP GETしたりする方法をまとめます。
JavaでJSON→Java、Java→JSON するやり方については**前稿**でまとめています
-
【本稿】JavaでHTTP通信でJSONをPOSTしたり、GETする方法についてまとめます
- JavaでHTTP通信をするやり方も2通り説明します
- OkHttp3を使ったやり方
- Java標準パッケージであるHttpUrlConnectionを使ったやり方
- JavaでHTTP通信をするやり方も2通り説明します
-
- JSONをJavaに変換(デシリアライズ)、JavaをJSONに変換(シリアライズ)するやり方は2通り説明します
- ライブラリにGSONを使うやり方
- ライブラリにJacksonを使うやり方
- JSONをJavaに変換(デシリアライズ)、JavaをJSONに変換(シリアライズ)するやり方は2通り説明します
準備
HTTP通信をする前にJava→JSON(シリアライズ)やJSON→Java(デシリアライズ)ができるようにする必要がある。
それをお手軽にやる方法は、こちらの記事にまとめているので、ここではスキップする。
サーバーからGETしたり、サーバーにPOSTするJSONは以下の形式としてコードを考える。
{
"person": {
"firstName": "John",
"lastName": "Doe",
"address": "NewYork",
"pets": [
{"type": "Dog", "name": "Jolly"},
{"type": "Cat", "name": "Grizabella"},
{"type": "Fish", "name": "Nimo"}
]
}
}
本稿では、HTTP通信するところにフォーカスする
JavaでHTTP通信する方法
2通りのアプローチを説明する
-
ライブラリ(OkHttp3)を使った方法
HTTP通信できるライブラリはたくさんあるが、本稿では OkHttp3 をとりあげる。 -
ライブラリを使わない方法
外部のライブラリを使わずJava標準パッケージ HttpUrlConnection を使う方法をとりあげる。
OkHttp3を使ってJSONをPOST、GETする
OkHttp3のライブラリ依存関係
OkHttp3のライブラリ指定方法は以下のとおり
■ OkHttp3の最新ライブラリ(mavenリポジトリ)
https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
■ OkHttp3のmaven設定例
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.1</version>
</dependency>
■ OkHttp3のgradle設定例
compile 'com.squareup.okhttp3:okhttp:3.14.1'
OkHttp3を使ってJSONをHTTP POSTする
JSON文字列をPOSTして、結果の文字列を受け取るHTTPクライアントのサンプルは以下のとおり
/**
* HTTPライブラリに「OkHttp3」、GSON操作ライブラリに「GSON」をつかって、
* サーバーにJSONを「POST」するサンプル
*/
public class OkHttpPostClient {
public static void main(String[] args) throws IOException {
OkHttpPostClient client = new OkHttpPostClient();
String result = client.callWebAPI();
System.out.println(result);
}
private static final String WEB_API_ENDPOINT = "http://localhost:8080/api";
public String callWebAPI() throws IOException {
final String postJson = "{" +
" \"person\": {" +
" \"firstName\": \"John\"," +
" \"lastName\": \"Doe\"," +
" \"address\": \"NewYork\"," +
" \"pets\": [" +
" {\"type\": \"Dog\", \"name\": \"Jolly\"}," +
" {\"type\": \"Cat\", \"name\": \"Grizabella\"}," +
" {\"type\": \"Fish\", \"name\": \"Nimo\"}" +
" ]" +
" }" +
"}";
final Map<String, String> httpHeaders = new LinkedHashMap<String, String>();
final String resultStr = doPost(WEB_API_ENDPOINT, "UTF-8", httpHeaders, postJson);
return resultStr;
}
public String doPost(String url, String encoding, Map<String, String> headers, String jsonString) throws IOException {
final okhttp3.MediaType mediaTypeJson = okhttp3.MediaType.parse("application/json; charset=" + encoding);
final RequestBody requestBody = RequestBody.create(mediaTypeJson, jsonString);
final Request request = new Request.Builder()
.url(url)
.headers(Headers.of(headers))
.post(requestBody)
.build();
final OkHttpClient client = new OkHttpClient.Builder()
.build();
final Response response = client.newCall(request).execute();
final String resultStr = response.body().string();
return resultStr;
}
}
OkHttp3を使ってJSONをHTTP GETする
GETするコードは以下の部分がポイントとなる。
以下ではurlとheaderを指定して、GETを実行する。
結果をテキストとして取得するには **response.body().string()**のようにする。
public String doGet(String url, Map<String, String> headers) throws IOException {
final Request request = new Request.Builder()
.url(url)
.headers(Headers.of(headers))
.build();
final OkHttpClient client = new OkHttpClient.Builder().build();
final Response response = client.newCall(request).execute();
final String resultStr = response.body().string();
return resultStr;
}
以下はフルソースコード。
http://localhost:8080/api にアクセスする例となる。
実験用にサーバー側のコードも下に掲載する。
public class OkHttpGetClient {
public static void main(String[] args) throws IOException {
OkHttpGetClient client = new OkHttpGetClient();
Model result = client.callWebAPI();
System.out.println("Firstname is " + result.person.firstName);
}
private static final String WEB_API_ENDPOINT = "http://localhost:8080/api";
private final Gson mGson = new Gson();
public Model callWebAPI() throws IOException {
final Map<String, String> httpHeaders = new LinkedHashMap<String, String>();
final String resultStr = doGet(WEB_API_ENDPOINT, httpHeaders);
final Model model = mGson.fromJson(resultStr, Model.class);
return model;
}
public String doGet(String url, Map<String, String> headers) throws IOException {
final Request request = new Request.Builder()
.url(url)
.headers(Headers.of(headers))
.build();
final OkHttpClient client = new OkHttpClient.Builder().build();
final Response response = client.newCall(request).execute();
final String resultStr = response.body().string();
return resultStr;
}
}
サーバー側のソースコード
実験用にサーバー側としてJettyをつかった簡易Web APIサーバーのコードを示す
/**
* ・GETされると、JSON文字列を返す<br>
* ・JSONをPOSTされると、JSONを解析して結果を返す<br>
* HTTPサーバー
*/
public class JsonApiServer {
public static void main(String[] args) {
final int PORT = 8080;
final Class<? extends Servlet> servlet = ExampleServlet.class;
ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletHandler.addServlet(new ServletHolder(servlet), "/api");
final Server jettyServer = new Server(PORT);
jettyServer.setHandler(servletHandler);
try {
jettyServer.start();
jettyServer.join();
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("serial")
public static class ExampleServlet extends HttpServlet {
private final Gson mGson = new Gson();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Model model = new Model();
model.person = new Person();
model.person.firstName = "ジョン";
model.person.lastName = "ドゥ";
model.person.address = "ニューヨーク";
model.person.pets = new ArrayList<Pet>();
Pet pet1 = new Pet();
pet1.type = "犬";
pet1.name = "ジョリー";
model.person.pets.add(pet1);
Pet pet2 = new Pet();
pet2.type = "猫";
pet2.name = "グリザベラ";
model.person.pets.add(pet2);
Pet pet3 = new Pet();
pet3.type = "魚";
pet3.name = "ニモ";
model.person.pets.add(pet3);
String json = mGson.toJson(model);
resp.setContentType("text/html; charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
final PrintWriter out = resp.getWriter();
out.println(json);
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final StringBuilder sb = new StringBuilder();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
}
final String body = sb.toString();
final Model model = mGson.fromJson(body, Model.class);
resp.setContentType("text/html; charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
final PrintWriter out = resp.getWriter();
out.println("Server Generated Message");
out.println("Firstname is " + model.person.firstName);
out.close();
}
}
}
ソースコード一式は以下となる
https://github.com/riversun/java-json-gson-jackson-http
HttpUrlConnectionを使ってJSONをPOST、GETする
依存ライブラリ
HttpUrlConnectionはJavaの標準パッケージなので、外部のライブラリなどは不要。
ライブラリは便利で洗練されている場合も多いが、例えば、Android環境のDEXファイル64Kの壁など、多機能なライブラリ導入による依存ライブラリ数増大・総メソッド数増大を回避をしたい場合など、まだ活用の余地がある。
HttpUrlConnectionを使ってJSONをHTTP POSTする
前述した通り、Android等Javaベースの環境でも幅広く使えるよう、記法はJava1.6 Compliantとした。
/**
* HTTP通信にはJava標準の「HttpUrlConnection」、GSON操作ライブラリに「GSON」をつかって、
* サーバーからJSONを「POST」するサンプル
*/
public class UrlConnHttpPostClient {
public static void main(String[] args) throws IOException {
UrlConnHttpPostClientclient = new UrlConnHttpPostClient();
String result = client.callWebAPI();
System.out.println(result);
}
private static final String WEB_API_ENDPOINT = "http://localhost:8080/api";
public String callWebAPI() throws IOException {
final String postJson = "{" +
" \"person\": {" +
" \"firstName\": \"John\"," +
" \"lastName\": \"Doe\"," +
" \"address\": \"NewYork\"," +
" \"pets\": [" +
" {\"type\": \"Dog\", \"name\": \"Jolly\"}," +
" {\"type\": \"Cat\", \"name\": \"Grizabella\"}," +
" {\"type\": \"Fish\", \"name\": \"Nimo\"}" +
" ]" +
" }" +
"}";
final Map<String, String> httpHeaders = new LinkedHashMap<String, String>();
final String resultStr = doPost(WEB_API_ENDPOINT, "UTF-8", httpHeaders, postJson);
return resultStr;
}
private String doPost(String url, String encoding, Map<String, String> headers, String jsonString) throws IOException {
final int TIMEOUT_MILLIS = 0;// タイムアウトミリ秒:0は無限
final StringBuffer sb = new StringBuffer("");
HttpURLConnection httpConn = null;
BufferedReader br = null;
InputStream is = null;
InputStreamReader isr = null;
try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
httpConn.setConnectTimeout(TIMEOUT_MILLIS);// 接続にかかる時間
httpConn.setReadTimeout(TIMEOUT_MILLIS);// データの読み込みにかかる時間
httpConn.setRequestMethod("POST");// HTTPメソッド
httpConn.setUseCaches(false);// キャッシュ利用
httpConn.setDoOutput(true);// リクエストのボディの送信を許可(GETのときはfalse,POSTのときはtrueにする)
httpConn.setDoInput(true);// レスポンスのボディの受信を許可
if (headers != null) {
for (String key : headers.keySet()) {
httpConn.setRequestProperty(key, headers.get(key));// HTTPヘッダをセット
}
}
final OutputStream os = httpConn.getOutputStream();
final boolean autoFlash = true;
final PrintStream ps = new PrintStream(os, autoFlash, encoding);
ps.print(jsonString);
ps.close();
final int responseCode = httpConn.getResponseCode();
String _responseEncoding = httpConn.getContentEncoding();
if (_responseEncoding == null) {
_responseEncoding = "UTF-8";
}
if (responseCode == HttpURLConnection.HTTP_OK) {
is = httpConn.getInputStream();
isr = new InputStreamReader(is, _responseEncoding);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} else {
// ステータスがHTTP_OK(200)以外の場合
throw new IOException("responseCode is " + responseCode);
}
} catch (IOException e) {
throw e;
} finally {
// Java1.6 Compliant
if (br != null) {
try {
br.close();
} catch (IOException e) {
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (httpConn != null) {
httpConn.disconnect();
}
}
return sb.toString();
}
}
HttpUrlConnectionを使ってJSONをHTTP GETする
package com.example.http_client.urlconnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import com.example.jackson.Model;
import com.google.gson.Gson;
/**
* HTTP通信にはJava標準の「HttpUrlConnection」、GSON操作ライブラリに「GSON」をつかって、
* サーバーからJSONを「GET」するサンプル
*/
public class UrlConnHttpGetClient {
public static void main(String[] args) throws IOException {
UrlConnHttpGetClient client = new UrlConnHttpGetClient();
Model result = client.callWebAPI();
System.out.println("Firstname is " + result.person.firstName);
}
private static final String WEB_API_ENDPOINT = "http://localhost:8080/api";
private final Gson mGson = new Gson();
public Model callWebAPI() throws IOException {
final Map<String, String> httpHeaders = new LinkedHashMap<String, String>();
final String resultStr = doGet(WEB_API_ENDPOINT, httpHeaders);
final Model model = mGson.fromJson(resultStr, Model.class);
return model;
}
public String doGet(String url, Map<String, String> headers) throws IOException {
final int TIMEOUT_MILLIS = 0;// タイムアウトミリ秒:0は無限
final StringBuffer sb = new StringBuffer("");
HttpURLConnection httpConn = null;
BufferedReader br = null;
InputStream is = null;
InputStreamReader isr = null;
try {
URL urlObj = new URL(url);
httpConn = (HttpURLConnection) urlObj.openConnection();
httpConn.setConnectTimeout(TIMEOUT_MILLIS);// 接続にかかる時間
httpConn.setReadTimeout(TIMEOUT_MILLIS);// データの読み込みにかかる時間
httpConn.setRequestMethod("GET");// HTTPメソッド
httpConn.setUseCaches(false);// キャッシュ利用
httpConn.setDoOutput(false);// リクエストのボディの送信を許可(GETのときはfalse,POSTのときはtrueにする)
httpConn.setDoInput(true);// レスポンスのボディの受信を許可
if (headers != null) {
for (String key : headers.keySet()) {
httpConn.setRequestProperty(key, headers.get(key));// HTTPヘッダをセット
}
}
final int responseCode = httpConn.getResponseCode();
String encoding = httpConn.getContentEncoding();
if (encoding == null) {
encoding = "UTF-8";
}
if (responseCode == HttpURLConnection.HTTP_OK) {
is = httpConn.getInputStream();
isr = new InputStreamReader(is, encoding);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} else {
// ステータスがHTTP_OK(200)以外の場合
throw new IOException("responseCode is " + responseCode);
}
} catch (IOException e) {
throw e;
} finally {
// Java1.6 Compliant
if (br != null) {
try {
br.close();
} catch (IOException e) {
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (httpConn != null) {
httpConn.disconnect();
}
}
return sb.toString();
}
}
まとめ
-
JavaでHTTP通信をするやり方も2通り紹介しました
- OkHttp3を使ったやり方
- Java標準パッケージであるHttpUrlConnectionを使ったやり方
-
全ソースコードはこちらにあります