JavaでURLからjsonを読み取る最も簡単な方法


245

これはばかげた質問かもしれませんが、読んで解析するための最も簡単な方法何でJSONをからURLJavaは

Groovyでは、これは数行のコードの問題です。私が見つけたJavaの例は途方もなく長い(そして巨大な例外処理ブロックがある)。

私がしたいのは、このリンクの内容を読むことだけです。


9
宣言されたすべての例外をJavaが強制的に処理するため、例外処理が必要です。例外処理の何が問題になっていますか?
Falmarri、2010年

3
さて、「java force you」が最大の問題です
ジョナタンクルーティエ、2015年

9
Javaが例外を処理するように強制しなかった場合、プログラムは引き続き実行され、正常に実行されると思いますか?プログラムに年齢を入力するように求められ、snarfleblaggerを入力として入力した場合はどうなりますか?Javaは問題なくプログラムを実行することを許可する必要がありますか?例外を処理したくない場合は、例外が発生する可能性のあるメソッドによってスローされるものとしてそれらを宣言し、何かが完全に正しくないときにプログラムが失敗することを確認してください。
Richard Barker

2
まったく馬鹿げた質問ではありません。特に、これを実行して実行できるPHPから来ていますjson_decode(file_get_contents($url));
dtbarne

回答:


193

Mavenアーティファクトorg.json:jsonを使用して、次のコードを取得しましたが、これは非常に短いと思います。できるだけ短くはありませんが、まだ使用可能です。

package so4308554;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;

import org.json.JSONException;
import org.json.JSONObject;

public class JsonReader {

  private static String readAll(Reader rd) throws IOException {
    StringBuilder sb = new StringBuilder();
    int cp;
    while ((cp = rd.read()) != -1) {
      sb.append((char) cp);
    }
    return sb.toString();
  }

  public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
    InputStream is = new URL(url).openStream();
    try {
      BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
      String jsonText = readAll(rd);
      JSONObject json = new JSONObject(jsonText);
      return json;
    } finally {
      is.close();
    }
  }

  public static void main(String[] args) throws IOException, JSONException {
    JSONObject json = readJsonFromUrl("https://graph.facebook.com/19292868552");
    System.out.println(json.toString());
    System.out.println(json.get("id"));
  }
}

3
1文字ずつ読み取る代わりに、BufferedReaderでreadLine()を使用できます。これにより、whileループの反復回数が減ります。
kdabir 2010

6
何のために?次にreadLine関数がループを実行し、文字の代わりに行を連結する必要があります。これでは、コードを現在ほど短くすることはできません。さらに、JSON表記では「行」の概念がないので、なぜそれをそのように読まなければならないのですか?
Roland Illig、2010

4
Apache commons-ioのIOUtils.toString(InputStream)方法を考えてみましょう。それはあなたにいくつかの行と責任を節約するはずです。
Mark Tielemans、

3
JSONObject json = new JSONObject(jsonText);の行でこのエラー「コンストラクターJSONObject(String)が未定義です」が発生する理由 「readJsonFromUrl」メソッドで..?@RolandIllig
Karthick pop

2
GSON、Jackson、Boon、Gensonなどでは、ソースのみをフィードする必要があります。URLのみ、または多くてもInputStreamです。上記のコードはorg.json使用方法が短い場合がありますが、他のライブラリが利用可能であることを確認してください。このタスクでは、1〜3行を超えるコードを記述する必要はありません。
StaxMan 2015年

68

以下は、Jacksonを使用したいくつかの代替バージョンです(データとして複数の方法があるため)。

  ObjectMapper mapper = new ObjectMapper(); // just need one
  // Got a Java class that data maps to nicely? If so:
  FacebookGraph graph = mapper.readValue(url, FaceBookGraph.class);
  // Or: if no class (and don't need one), just map to Map.class:
  Map<String,Object> map = mapper.readValue(url, Map.class);

具体的には、Javaオブジェクトを処理する通常の(IMO)ケースを1つのライナーにすることができます。

FacebookGraph graph = new ObjectMapper().readValue(url, FaceBookGraph.class);

Gsonのような他のライブラリも1行のメソッドをサポートしています。多くの例がはるかに長いセクションを示す理由は奇妙です。さらに悪いことに、多くの例では古いorg.jsonライブラリを使用しています。それが最初のことだったかもしれませんが、半ダースより良い選択肢があるので、それを使用する理由はほとんどありません。


ここのURLは何ですか?文字列、URLオブジェクト、またはbyte []ですか?
Dinesh 2015年

1
私が考えていたjava.net.URL1つの作品だけでなく、他の情報源の多くをが、どちらか(FileInputStreamReaderString)。
StaxMan 2015

4
それはすべき「のhttp:// ....」それ以外の場合は、文字列を解析しようとする、上記の例のjava.net.URLことがエラーを生成しますJSON、など
zbstof

@Zotovはい。渡すにStringは、コンテンツをJSONにする必要があります。使用するURI / URLのテキストエンコーディングではありません。
StaxMan 2016年

2
認識されないトークン「https」:予期していた(「true」、「false」、または「null」)
Damir Olejar

60

最も簡単な方法:Google独自のgoto jsonライブラリであるgsonを使用します。https://code.google.com/p/google-gson/

こちらがサンプルです。この無料のgeolocator Webサイトにアクセスして、jsonを解析し、郵便番号を表示します。(これをメインメソッドに入れてテストしてください)

    String sURL = "http://freegeoip.net/json/"; //just a string

    // Connect to the URL using java's native library
    URL url = new URL(sURL);
    URLConnection request = url.openConnection();
    request.connect();

    // Convert to a JSON object to print data
    JsonParser jp = new JsonParser(); //from gson
    JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
    JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object. 
    String zipcode = rootobj.get("zip_code").getAsString(); //just grab the zipcode

1
「NetworkOnMainThreadException」エラーが発生するのはなぜですか?AsyncTaskを使用する必要がありますか、それとも別の方法がありますか?この例では、このエラーも発生しましたか?
Benetz、2015年

rootobj.get("zip_code").getAsString();
タイプミス

jsonParserをインポートするにはどうすればよいですか?私は常にエラーを受け取ります:「エラー:(69、9)エラー:シンボルクラスJsonParserが見つかりません」
MAESTRO_DE

1
maven依存関係<dependency> <groupId> com.google.code.gson </ groupId> <artifactId> gson </ artifactId> <version> 2.8.0 </ version> </ dependency>を追加して、pomでJsonParseを取得してくださいファイル。
サシカンタ2017年

次のようにGsonを使用して、タイプセーフな方法で簡略化して処理できます。MyResponseObject response = new GsonBuilder()。create()。fromJson(new InputStreamReader((InputStream)request.getContent())、MyResponseObject.class);
グレゴール

42

いくつかのライブラリを使用しても構わない場合は、1行で実行できます。

インクルードのApache CommonsのIOUtilsjson.orgライブラリを。

JSONObject json = new JSONObject(IOUtils.toString(new URL("https://graph.facebook.com/me"), Charset.forName("UTF-8")));

依存関係をgradleに追加すると、このアプリがGoogle Pixel XLにインストールできなくなる理由について何か推測はありますか?
andrdoiddev 2017年

@andrdoiddev-別の質問として質問してください。これは、Apache Commons、Gradle、Android開発に対してより一般的です。
ezwrighter 2017年

1
これは今ではかなり古いですが、それでも良い解決策です。@ andrdoiddevまたは他の誰かがまだGradleの依存関係を必要とする場合に備えて、これらは私が使用しているものです:コンパイルグループ: 'org.json'、名前: 'json 」、バージョン: '20180813'コンパイルグループ: 'コモンズ-IO'、名前: 'コモンズ-IO'、バージョン: '2.6'
R02

複数のリクエストを発行し、json応答をJSONArrayに保存してから、FileWriterを使用してJSONArrayをファイルに書き込んだ場合、このライブラリは二重引用符をエスケープしません。これにより、ファイルを簡単に解析してJSONArrayに戻すことができます。
Gh0sT

6

HttpClientを使用して、URLのコンテンツを取得します。次に、json.orgのライブラリを使用してJSONを解析します。私は多くのプロジェクトでこれら2つのライブラリーを使用してきましたが、それらは堅牢で使いやすいものでした。

それ以外の場合は、Facebook API Javaライブラリを使用してみてください。私はこの分野での経験はありませんが、JavaでFacebook API使用することに関連するスタックオーバーフローに関する質問があります。ライブラリを使用するのに適した選択肢としてRestFBを検討することをお勧めします。


5

私はjsonパーサーを最も簡単な方法で実行しました、ここにあります

package com.inzane.shoapp.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

public JSONObject getJSONFromUrl(String url) {

    // Making HTTP request
    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
            System.out.println(line);
        }
        is.close();
        json = sb.toString();

    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
        System.out.println("error on parse data in jsonparser.java");
    }

    // return JSON String
    return jObj;

}
}

このクラスは、URLからjsonオブジェクトを返します

そしてjsonオブジェクトが必要なときは、このクラスとActivityクラスのメソッドを呼び出すだけです

私のコードはここにあります

String url = "your url";
JSONParser jsonParser = new JSONParser();
JSONObject object = jsonParser.getJSONFromUrl(url);
String content=object.getString("json key");

ここで、「jsonキー」は、jsonファイルのキー

これは単純なjsonファイルの例です

{
    "json":"hi"
}

ここで、「json」がキーで、「hi」が値です

これにより、json値が文字列コンテンツに取得されます。


1
それは「最も簡単な方法」ではないと思います
単独で

3

jersey-clientを使用すると、このmaven依存関係を含めるだけで非常に簡単です。

<dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-client</artifactId>
  <version>2.25.1</version>
</dependency>

次に、この例を使用して呼び出します。

String json = ClientBuilder.newClient().target("http://api.coindesk.com/v1/bpi/currentprice.json").request().accept(MediaType.APPLICATION_JSON).get(String.class);

次に、GoogleのGsonを使用してJSONを解析します。

Gson gson = new Gson();
Type gm = new TypeToken<CoinDeskMessage>() {}.getType();
CoinDeskMessage cdm = gson.fromJson(json, gm);

答えに反することは何もありませんが、jersey-clientパッケージに関する非常に多くの問題...それはエラーの混乱です。
Johnny Bigoode 2017年

私はそれで問題に遭遇していません。いくつかの詳細や代替案を指摘できますか?
user3892260 2017年

私が見つけた問題はclassnotfoundエラーに関連しており、何とか修正できなかったため、原因は正確にはわかりませんでした。
Johnny Bigoode 2017年

3

私はこれが断然最も簡単な方法であることを発見しました。

この方法を使用します。

public static String getJSON(String url) {
        HttpsURLConnection con = null;
        try {
            URL u = new URL(url);
            con = (HttpsURLConnection) u.openConnection();

            con.connect();


            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            br.close();
            return sb.toString();


        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (con != null) {
                try {
                    con.disconnect();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        return null;
    }

次のように使用します。

String json = getJSON(url);
JSONObject obj;
   try {
         obj = new JSONObject(json);
         JSONArray results_arr = obj.getJSONArray("results");
         final int n = results_arr.length();
            for (int i = 0; i < n; ++i) {
                // get the place id of each object in JSON (Google Search API)
                String place_id = results_arr.getJSONObject(i).getString("place_id");
            }


   }

そこにClassCastException例外が発生しています。次の行を変更しますu = new URL(url); このURLにu = new URL(null、url、new sun.net.www.protocol.https.Handler()); このコードが機能するため
晴れたarya

2

これが効率的かどうかはわかりませんが、これは可能な方法の1つです。

URLの使用からjson url.openStream()を読み取り、コンテンツを文字列に読み取ります。

この文字列でJSONオブジェクトを作成します(詳細はjson.orgで

JSONObject(java.lang.String source)
      Construct a JSONObject from a source JSON text string.

0

JDKの(やや)最近の更新により、HTTP URLの内容が少し読みやすくなったので、ここに更新された回答を追加したいと思いました。他の人が言ったように、JDKには現在含まれていないため、解析を行うにはJSONライブラリを使用する必要があります。Javaで最もよく使用されるJSONライブラリのいくつかを次に示します。

URLからJSONを取得するには、これは厳密にJDKクラスを使用する最も簡単な方法のようです(ただし、大きなペイロードに対して実行したくないものです)。Java9が導入されました:https : //docs.oracle.com/en/ java / javase / 11 / docs / api / java.base / java / io / InputStream.html#readAllBytes()

try(java.io.InputStream is = new java.net.URL("https://graph.facebook.com/me").openStream()) {
    String contents = new String(is.readAllBytes());
}

たとえば、GSONライブラリを使用してJSONを解析するには

com.google.gson.JsonElement element = com.google.gson.JsonParser.parseString(contents); //from 'com.google.code.gson:gson:2.8.6'

0

以下は、Jsonコンテンツを解析する方法の完全なサンプルです。この例では、Androidバージョンの統計情報を取得しいます(ここにリンクしている Android Studioのソースコードはこちらにあります)。

そこから取得した「distributions.json」ファイルを、代替としてres / rawにコピーします。

build.gradle

    implementation 'com.google.code.gson:gson:2.8.6'

マニフェスト

  <uses-permission android:name="android.permission.INTERNET" />

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if (savedInstanceState != null)
            return
        thread {
            // https://cs.android.com/android/platform/superproject/+/studio-master-dev:tools/adt/idea/android/src/com/android/tools/idea/stats/DistributionService.java
            var root: JsonArray
            Log.d("AppLog", "loading...")
            try {
                HttpURLConnection.setFollowRedirects(true)
                val statsUrl = "https://dl.google.com/android/studio/metadata/distributions.json" //just a string
                val url = URL(statsUrl)
                val request: HttpURLConnection = url.openConnection() as HttpURLConnection
                request.connectTimeout = 3000
                request.connect()
                InputStreamReader(request.content as InputStream).use {
                    root = JsonParser.parseReader(it).asJsonArray
                }
            } catch (e: Exception) {
                Log.d("AppLog", "error while loading from Internet, so using fallback")
                e.printStackTrace()
                InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
                    root = JsonParser.parseReader(it).asJsonArray
                }
            }
            val decimalFormat = DecimalFormat("0.00")
            Log.d("AppLog", "result:")

            root.forEach {
                val androidVersionInfo = it.asJsonObject
                val versionNickName = androidVersionInfo.get("name").asString
                val versionName = androidVersionInfo.get("version").asString
                val versionApiLevel = androidVersionInfo.get("apiLevel").asInt
                val marketSharePercentage = androidVersionInfo.get("distributionPercentage").asFloat * 100f
                Log.d("AppLog", "\"$versionNickName\" - $versionName - API$versionApiLevel - ${decimalFormat.format(marketSharePercentage)}%")
            }
        }
    }
}

依存関係の代わりに、これを代わりに使用することもできます:

InputStreamReader(request.content as InputStream).use {
    val jsonArray = JSONArray(it.readText())
}

そしてフォールバック:

InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
    val jsonArray = JSONArray(it.readText())
}

これを実行した結果:

loading...
result:
"Ice Cream Sandwich" - 4.0 - API15 - 0.20%
"Jelly Bean" - 4.1 - API16 - 0.60%
"Jelly Bean" - 4.2 - API17 - 0.80%
"Jelly Bean" - 4.3 - API18 - 0.30%
"KitKat" - 4.4 - API19 - 4.00%
"Lollipop" - 5.0 - API21 - 1.80%
"Lollipop" - 5.1 - API22 - 7.40%
"Marshmallow" - 6.0 - API23 - 11.20%
"Nougat" - 7.0 - API24 - 7.50%
"Nougat" - 7.1 - API25 - 5.40%
"Oreo" - 8.0 - API26 - 7.30%
"Oreo" - 8.1 - API27 - 14.00%
"Pie" - 9.0 - API28 - 31.30%
"Android 10" - 10.0 - API29 - 8.20%
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.