जावा में URL से json पढ़ने का सबसे सरल तरीका


245

यह एक गूंगा प्रश्न हो सकता है लेकिन JSON को URL से पढ़ने और पार्स करने का सबसे सरल तरीका क्या है जावा में ?

ग्रूवी में, यह कोड की कुछ पंक्तियों की बात है। जावा के उदाहरण जो मुझे मिले वे हास्यास्पद रूप से लंबे हैं (और विशाल अपवाद हैंडलिंग ब्लॉक है)।

मैं केवल इतना करना चाहता हूं कि इस लिंक की सामग्री को पढ़ें ।


9
अपवाद की हैंडलिंग आवश्यक है क्योंकि जावा आपको किसी भी अपवाद को संभालने के लिए मजबूर करता है। अपवाद से निपटने में क्या गलत है?
फाल्मरी

3
ठीक है, "जावा फोर्स
यू

9
यदि जावा ने आपको अपवादों को संभालने के लिए मजबूर नहीं किया है, तो क्या आपको लगता है कि कार्यक्रम अभी भी चलेंगे और अच्छी तरह से चलेंगे? क्या होगा यदि मुझे एक कार्यक्रम में मेरी उम्र का इनपुट करने के लिए कहा गया और मैंने अपने इनपुट के रूप में स्नारफ्लेब्लागर दिया? क्या जावा को प्रोग्राम को बिना किसी मुद्दे के केवल निष्पादित करने की अनुमति देनी चाहिए? यदि आप अपवादों को संभालना नहीं चाहते हैं, तो उन्हें उन तरीकों से फेंके जाने की घोषणा करें, जो वे हो सकते हैं और जब आपका कार्यक्रम पूरी तरह से सही नहीं होता है, तो अपने कार्यक्रम को विफल देखें।
रिचर्ड बार्कर

2
एक गूंगा सवाल बिल्कुल नहीं। विशेष रूप से PHP से आ रहा है जहाँ आप ऐसा कर सकते हैं json_decode(file_get_contents($url));और किया जा सकता है!
dtbarne

जवाबों:


193

मावेन विरूपण साक्ष्य का उपयोग करके 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
चरित्र द्वारा चरित्र पढ़ने के बजाय आप बफ़ररएडर पर रीडलाइन () का उपयोग कर सकते हैं। यह लूप करते समय पुनरावृत्तियों की संख्या को कम करेगा।
kdabir 12

6
किस लिए? readLineसमारोह पाश तो क्या करेंगे, और मैं, अक्षरों के स्थान पर लाइनों को श्रेणीबद्ध करने के लिए जो और अधिक महंगा है। कोड को अब जितना छोटा रखा जाएगा उतना कम नहीं रखा जाएगा। इसके अलावा, JSON अंकन में "लाइनों" की कोई अवधारणा नहीं है, इसलिए मुझे उन्हें इस तरह क्यों पढ़ना चाहिए?
रोलैंड इलिग

4
Apache commons-io की IOUtils.toString(InputStream)विधि पर विचार करें । जिससे आपको कुछ लाइनों और जिम्मेदारी को बचाना चाहिए।
मार्क टाईलेमैन्स

3
JSONObject json = new JSONObject (jsonText) की पंक्ति में मुझे यह त्रुटि "कंस्ट्रक्टर JSONObject (स्ट्रिंग) अपरिभाषित है" अपरिभाषित है; "readJsonFromUrl" विधि में ..? @ रोलैंडिग
कार्तिक पॉप

2
GSON, जैक्सन, बून, गेंसन और अन्य के साथ, आपको केवल स्रोत को खिलाने की आवश्यकता है: या तो केवल URL, या अधिकतम InputStream। हालांकि उपरोक्त कोड org.jsonउपयोग के लिए छोटा हो सकता है , लेकिन उपलब्ध अन्य कामों को सत्यापित करना सुनिश्चित करें - इस कार्य के लिए कोड की 1-3 से अधिक पंक्तियों को लिखने की आवश्यकता नहीं है।
स्टेक्समैन

68

यहाँ जैक्सन के साथ कुछ वैकल्पिक संस्करण दिए गए हैं (क्योंकि एक से अधिक तरीके हैं जिनसे आप डेटा चाह सकते हैं):

  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);

और विशेष रूप से सामान्य (IMO) मामला जहां आप जावा ऑब्जेक्ट से निपटना चाहते हैं, को एक लाइनर बनाया जा सकता है:

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

Gson जैसे अन्य कार्य भी एक-लाइन विधियों का समर्थन करते हैं; क्यों कई उदाहरण बहुत लंबे वर्गों को दिखाते हैं। और इससे भी बदतर यह है कि कई उदाहरण अप्रचलित org.json लाइब्रेरी का उपयोग करते हैं; हो सकता है कि यह पहली चीज हो, लेकिन इसके आधा दर्जन बेहतर विकल्प हैं, इसलिए इसका उपयोग करने की बहुत कम वजह है।


यहाँ url क्या है? क्या यह एक स्ट्रिंग या URL ऑब्जेक्ट या बाइट [] है?
दिनेश

1
मैं के बारे में सोच रहा था java.net.URL, लेकिन या तो एक काम करता है, और साथ ही अन्य स्रोतों के बहुत सारे ( File, InputStream, Reader, String)।
StaxMan

4
यह ऊपर दिए गए उदाहरण में java.net.URL होना चाहिए , अन्यथा यह स्ट्रिंग 'http: // ....' को पार्स करने का प्रयास करेगा, जो कि एक त्रुटि के रूप में होगा
zbstof

@Zotov हाँ। पासिंग के Stringलिए JSON होने के लिए सामग्री की आवश्यकता होगी, न कि उपयोग करने के लिए URI / URL की शाब्दिक एन्कोडिंग।
स्टैक्मैन मैन

2
गैर-मान्यता प्राप्त टोकन 'https': उम्मीद कर रहा था ('सही', 'गलत' या 'अशक्त')
दामिर ओलेजर

60

सबसे आसान तरीका: Google का उपयोग करें, Google का अपना गोटो जेनसन लाइब्रेरी है। https://code.google.com/p/google-gson/

यहाँ एक नमूना है। मैं इस मुफ्त जियोलोकेटर वेबसाइट पर जा रहा हूं और जसन को पार्स कर रहा हूं और अपना जिपकोड प्रदर्शित कर रहा हूं। (बस इसे जांचने के लिए इस सामग्री को एक मुख्य विधि में डालें)

    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 उपयोगकर्ता करना चाहिए या कोई अन्य तरीका है? इस उदाहरण में आपको यह त्रुटि भी मिली?
बेनेट्ज़

टाइपो, होना चाहिए:rootobj.get("zip_code").getAsString();
लूपसम

मैं jsonParser को कैसे आयात करूं? मुझे हमेशा त्रुटि मिलती है: 'त्रुटि: (69, 9) त्रुटि: प्रतीक वर्ग JsonParser नहीं ढूँढ सकता'
MAESTRO_DE

1
कृपया अपने पोम में JsonParse प्राप्त करने के लिए maven निर्भरता <निर्भरता> <groupId> com.google.code.gson </ groupId> <विरूपण साक्ष्य> gson </ विरूपण साक्ष्य> <संस्करण> 2.8.0 </ संस्करण> </ निर्भरता> जोड़ें फ़ाइल।
शशिकांत

सरल किया जा सकता है और Gson के साथ एक प्रकार से नियंत्रित किया जा सकता है: MyResponseObject response = new GsonBuilder () create। ()। fromJson (नया InputStreamReader ((InputStream): request .getContent ()), MyResponseObject.class);
ग्रेगोर

42

यदि आप एक दो पुस्तकालयों का उपयोग करने में कोई आपत्ति नहीं करते हैं तो इसे एक ही पंक्ति में किया जा सकता है।

अपाचे कॉमन्स IOUtils & json.org लाइब्रेरी शामिल करें ।

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

क्या आपके पास इस बात का कोई अनुमान है कि ग्रेडेल पर निर्भरता को जोड़ने से इस ऐप को मेरे Google Pixel XL पर इंस्टॉल होने से कैसे रोका जा सकेगा?
andrdoiddev

@andrdoiddev - आपको एक अलग प्रश्न के रूप में पूछना चाहिए। यह Apache Commons, Gradle और Android Development के लिए अधिक सामान्य है।
एज़राइटर

1
यह अब काफी पुराना है, लेकिन अभी भी एक अच्छा समाधान है, इसलिए सिर्फ @andrdoiddev या किसी और को अभी भी ग्रैडल निर्भरता की आवश्यकता है, ये वे हैं जो मैं उपयोग कर रहा हूं: संकलन समूह: 'org.json', नाम: 'json ', संस्करण:' 20180813 'संकलन समूह:' कॉमन्स-आईओ ', नाम:' कॉमन्स-आईओ ', संस्करण:' 2.6 '
r02

मान लें कि आप कई अनुरोधों को पूरा कर रहे हैं, एक JSONArray के जसन प्रतिक्रियाओं को सहेजना और फिर FileWriter का उपयोग करके किसी फ़ाइल के लिए JSONArray लिखना, फिर यह लाइब्रेरी डबल ESCAPE नहीं है। यह फ़ाइल को JSONArray में आसानी से पार्स कर देता है।
घोट्स

6

URL की सामग्री को हथियाने के लिए HttpClient का उपयोग करें । और फिर json.org से लाइब्रेरी का उपयोग करें करके JSON को पार्स करें। मैंने कई परियोजनाओं पर इन दो पुस्तकालयों का उपयोग किया है और वे उपयोग करने के लिए मजबूत और सरल रहे हैं।

इसके अलावा आप फेसबुक एपीआई जावा लाइब्रेरी का उपयोग करने का प्रयास कर सकते हैं। मुझे इस क्षेत्र में कोई अनुभव नहीं है, लेकिन जावा में फेसबुक एपीआई का उपयोग करने से संबंधित स्टैक ओवरफ्लो पर सवाल है । आप लाइब्रेरी का उपयोग करने के लिए रेस्टफ बी को एक अच्छे विकल्प के रूप में देखना चाह सकते हैं ।


5

मैंने सबसे सरल तरीके से json parser किया है, यहाँ यह है

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 ऑब्जेक्ट लौटाता है

और जब आप जैसन ऑब्जेक्ट चाहते हैं तो आप इस क्लास और मेथड को अपनी एक्टिविटी क्लास कहते हैं

मेरा कोड यहाँ है

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

यहाँ पर "json key" को दर्शाया गया है कि आपकी json फाइल में कुंजी है

यह एक सरल json फ़ाइल उदाहरण है

{
    "json":"hi"
}

यहाँ "json" कुंजी है और "hi" मान है

यह स्ट्रिंग सामग्री के लिए आपके json मान प्राप्त करेगा।


1
मुझे लगता है कि यह "सबसे सरल तरीका" नहीं है
अकेले

3

जर्सी-क्लाइंट का उपयोग करना बहुत आसान है, बस इस मावेन निर्भरता को शामिल करें:

<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);

तब JSON को पार्स करने के लिए Google के Gson का उपयोग करें:

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

जवाब के खिलाफ कुछ भी नहीं, लेकिन जर्सी-क्लाइंट पैकेज के साथ इतने सारे मुद्दे ... यह त्रुटियों का एक गड़बड़ है।
जॉनी बिगोड

मैं इसके साथ किसी भी मुद्दे का सामना नहीं किया है। क्या आप कुछ बारीकियों और / या विकल्पों को इंगित कर सकते हैं?
user3892260

मुझे जो समस्याएं मिलीं, वे क्लास नोटफ़ाउंड त्रुटि से संबंधित थीं, कारण के बारे में बिल्कुल निश्चित नहीं थीं, क्योंकि मैंने इसे ठीक करने का प्रबंधन नहीं किया था।
जॉनी बिगोडे

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 अपवाद मिला है। लाइन URL u = नया URL (url) बदलें; इस URL के लिए = नया URL (null, url, new sun.net.www.protocol.https.Handler ()); इस कोड को काम करने के लिए
सनी आर्य

2

मुझे यकीन नहीं है कि यह कुशल है, लेकिन यह संभव तरीकों में से एक है:

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 की सामग्री को पढ़ना थोड़ा आसान बना दिया है। जैसा कि अन्य लोगों ने कहा है, आपको अभी भी पार्सिंग करने के लिए JSON लाइब्रेरी का उपयोग करना होगा, क्योंकि JDK में वर्तमान में एक नहीं है। यहाँ जावा के लिए सबसे अधिक इस्तेमाल की जाने वाली JSON लाइब्रेरी हैं:

किसी URL से JSON को पुनः प्राप्त करने के लिए, यह JDK कक्षाओं का कड़ाई से उपयोग करने का सबसे सरल तरीका लगता है (लेकिन शायद कुछ ऐसा नहीं जिसे आप बड़े पेलोड के लिए करना चाहते हैं), Java 9 ने पेश किया: https://docs.oracle.com/en/ जावा / JavaSE / 11 / docs / api / java.base / जावा / कब / 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 सामग्री को पार्स करने के तरीके का एक पूरा नमूना है। उदाहरण एंड्रॉइड वर्जन के आँकड़े लेता है (एंड्रॉइड स्टूडियो स्रोत कोड से यहां पाया गया है , जो यहां लिंक करता है )।

"वितरण। जेसन" फ़ाइल को कॉपी करें जो आपको वहां से रिस / कच्चे में मिलती है, एक कमबैक के रूप में।

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%
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.