Java: аналогичная функция для PHP: доступен json_decode? [Дубликат]

Когда ваши пути include разные

Ошибки компоновщика могут произойти, если заголовочный файл и связанная с ним общая библиотека (файл .lib) не синхронизируются. Позволь мне объяснить.

Как работают линкеры? Линкер соответствует объявлению функции (объявленному в заголовке) с его определением (в общей библиотеке) путем сравнения их подписи. Вы можете получить ошибку компоновщика, если компоновщик не найдет определение функции, которое идеально подходит.

Возможно ли получить ошибку компоновщика, даже если объявление и определение, похоже, совпадают? Да! Они могут выглядеть одинаково в исходном коде, но это действительно зависит от того, что видит компилятор. По сути, вы можете столкнуться с такой ситуацией:

// header1.h
typedef int Number;
void foo(Number);

// header2.h
typedef float Number;
void foo(Number); // this only looks the same lexically

Обратите внимание, что хотя обе декларации функций выглядят одинаково в исходном коде, но они действительно различаются в зависимости от компилятора.

Вы можете спросить, как это получается в такой ситуации? Включите пути, конечно! Если при компиляции разделяемой библиотеки путь include приводит к header1.h, и вы в конечном итоге используете header2.h в своей собственной программе, вы оставите царапины на своем заголовке, задаваясь вопросом, что произошло (каламбур).

Пример того, как это может произойти в реальном мире, объясняется ниже.

Дальнейшая разработка с примером

У меня есть два проекта: graphics.lib и main.exe. Оба проекта зависят от common_math.h. Предположим, что библиотека экспортирует следующую функцию:

// graphics.lib    
#include "common_math.h" 

void draw(vec3 p) { ... } // vec3 comes from common_math.h

И затем вы идете вперед и включаете библиотеку в свой собственный проект.

// main.exe
#include "other/common_math.h"
#include "graphics.h"

int main() {
    draw(...);
}

Boom! Вы получаете ошибку компоновщика, и вы понятия не имеете, почему она терпит неудачу. Причина в том, что общая библиотека использует разные версии одного и того же include common_math.h (я сделал это очевидным здесь в этом примере, включив другой путь, но это может быть не всегда так очевидно. Возможно, путь include отличается в настройки компилятора).

Обратите внимание, что в этом примере компоновщик сказал бы вам, что не смог найти draw(), когда на самом деле вы знаете, что он явно экспортируется библиотекой. Вы могли часами царапать себе голову, думая, что пошло не так. Дело в том, что компоновщик видит другую подпись, потому что типы параметров немного отличаются. В этом примере vec3 является другим типом в обоих проектах в отношении компилятора. Это может произойти из-за того, что они происходят из двух немного разных файлов include (возможно, включенные файлы поступают из двух разных версий библиотеки).

Отладка компоновщика

DUMPBIN - ваш друг, если вы используете Visual Studio. Я уверен, что другие компиляторы имеют другие подобные инструменты.

Процесс выглядит следующим образом:

  1. Обратите внимание на странное искаженное имя, указанное в ошибке компоновщика. (например, draw @ graphics @ XYZ).
  2. Выгрузите экспортированные символы из библиотеки в текстовый файл.
  3. Найдите экспортированный символ, представляющий интерес, и обратите внимание, что искаженное имя
  4. Обратите внимание на то, почему искаженные имена оказались разными. Вы могли бы видеть, что типы параметров различны, хотя они выглядят одинаково в исходном коде.
  5. Причина, почему они разные. В приведенном выше примере они различаются из-за разных файлов include.

[1] По проекту я имею в виду набор исходных файлов, которые связаны друг с другом для создания либо библиотеки, либо исполняемого файла .

РЕДАКТИРОВАТЬ 1: Переписать первый раздел, который будет легче понять. Пожалуйста, прокомментируйте ниже, чтобы сообщить мне, нужно ли что-то еще исправлять. Спасибо!

203
задан Atish Dipongkor 2 August 2013 в 11:32
поделиться

8 ответов

Самый простой способ: использовать gson, собственную библиотеку goo json в Google. https://code.google.com/p/google-gson/

Вот пример. Я перехожу на этот бесплатный сайт геолокатора и разбираю 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
44
ответ дан Ad Infinitum 25 August 2018 в 11:32
поделиться

Если вы не возражаете использовать несколько библиотек, это может быть сделано в одной строке.

Включить Apache Commons IOUtils & amp; json.org .

JSONObject json = new JSONObject(IOUtils.toString(new URL("https://graph.facebook.com/me"), Charset.forName("UTF-8")));
26
ответ дан ezwrighter 25 August 2018 в 11:32
поделиться

Я не уверен, что это эффективно, но это один из возможных способов:

Прочитать json из url use url.openStream() и прочитать содержимое в строку.

построить объект JSON с этой строкой (подробнее в json.org )

JSONObject(java.lang.String source)
      Construct a JSONObject from a source JSON text string.
2
ответ дан kunal 25 August 2018 в 11:32
поделиться

Я сделал парсер 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;

}
}

этот класс возвращает объект json из url

, и если вы хотите, чтобы json-объект вы просто вызовите этот класс и метод в свой класс Activity

мой код здесь

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 будет содержать строковое содержимое.

5
ответ дан L84 25 August 2018 в 11:32
поделиться

Используйте HttpClient , чтобы захватить содержимое URL-адреса. А затем используйте библиотеку из json.org для разбора JSON. Я использовал эти две библиотеки для многих проектов, и они были прочными и простыми в использовании.

Помимо этого вы можете попробовать использовать java-библиотеку Facebook API. У меня нет опыта в этой области, но есть вопрос о переполнении стека, относящемся к , используя API Facebook в java . Вы можете посмотреть RestFB как хороший выбор для использования библиотеки.

6
ответ дан ojonugwa ochalifu 25 August 2018 в 11:32
поделиться

Используя артефакт 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"));
  }
}
166
ответ дан Roland Illig 25 August 2018 в 11:32
поделиться

Вот несколько альтернативных версий с 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);

И, в частности, обычная (IMO) случай, когда вы хотите иметь дело с объектами Java, может быть сделан одним лайнером:

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

Другие библиотеки, такие как Gson, также поддерживают однострочные методы; почему многие примеры показывают, что более длинные разделы являются нечетными. И еще хуже то, что во многих примерах используется устаревшая библиотека org.json; это, возможно, было первым делом, но есть полдюжины лучших альтернатив, поэтому есть очень мало оснований для его использования.

59
ответ дан StaxMan 25 August 2018 в 11:32
поделиться

Очень просто, используя 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);
4
ответ дан user3892260 25 August 2018 в 11:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: