JSON 입력 스트림을 해석하는 방법
java를 사용하여 JSON 개체를 반환하는 URL을 호출하고 있습니다.
url = new URL("my URl");
urlInputStream = url.openConnection().getInputStream();
응답을 문자열 형식으로 변환하고 해석하려면 어떻게 해야 합니까?
InputStream을 변환하려면 Reader를 사용해야 합니다.
BufferedReader streamReader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
responseStrBuilder.append(inputStr);
new JSONObject(responseStrBuilder.toString());
in.toString()을 시도했지만 다음과 같이 반환됩니다.
getClass().getName() + '@' + Integer.toHexString(hashCode())
(개체에서 toString으로 파생된다고 기재되어 있는 문서와 같습니다)
현재의 답변은 모두 입력 스트림을 조금씩 읽을 수 있는 것이 장점인 경우 JSON 전체를 메모리로 가져와도 괜찮다고 가정하고 있습니다.Json 파일 전체를 한 번에 읽는 것을 피하고 싶다면 잭슨 라이브러리를 사용하는 것이 좋습니다(개인적으로는 마음에 들지만 Gson과 같은 다른 사람들도 비슷한 기능을 가지고 있을 것입니다).
Jackson에서는 JsonParser를 사용하여 한 번에 한 섹션을 읽을 수 있습니다.다음은 반복기에서 JsonObjects 배열 읽기를 랩하는 코드의 예입니다.Jackson의 예만 보려면 initJsonParser, initFirstElement 및 initNextObject 메서드를 참조하십시오.
public class JsonObjectIterator implements Iterator<Map<String, Object>>, Closeable {
private static final Logger LOG = LoggerFactory.getLogger(JsonObjectIterator.class);
private final InputStream inputStream;
private JsonParser jsonParser;
private boolean isInitialized;
private Map<String, Object> nextObject;
public JsonObjectIterator(final InputStream inputStream) {
this.inputStream = inputStream;
this.isInitialized = false;
this.nextObject = null;
}
private void init() {
this.initJsonParser();
this.initFirstElement();
this.isInitialized = true;
}
private void initJsonParser() {
final ObjectMapper objectMapper = new ObjectMapper();
final JsonFactory jsonFactory = objectMapper.getFactory();
try {
this.jsonParser = jsonFactory.createParser(inputStream);
} catch (final IOException e) {
LOG.error("There was a problem setting up the JsonParser: " + e.getMessage(), e);
throw new RuntimeException("There was a problem setting up the JsonParser: " + e.getMessage(), e);
}
}
private void initFirstElement() {
try {
// Check that the first element is the start of an array
final JsonToken arrayStartToken = this.jsonParser.nextToken();
if (arrayStartToken != JsonToken.START_ARRAY) {
throw new IllegalStateException("The first element of the Json structure was expected to be a start array token, but it was: " + arrayStartToken);
}
// Initialize the first object
this.initNextObject();
} catch (final Exception e) {
LOG.error("There was a problem initializing the first element of the Json Structure: " + e.getMessage(), e);
throw new RuntimeException("There was a problem initializing the first element of the Json Structure: " + e.getMessage(), e);
}
}
private void initNextObject() {
try {
final JsonToken nextToken = this.jsonParser.nextToken();
// Check for the end of the array which will mean we're done
if (nextToken == JsonToken.END_ARRAY) {
this.nextObject = null;
return;
}
// Make sure the next token is the start of an object
if (nextToken != JsonToken.START_OBJECT) {
throw new IllegalStateException("The next token of Json structure was expected to be a start object token, but it was: " + nextToken);
}
// Get the next product and make sure it's not null
this.nextObject = this.jsonParser.readValueAs(new TypeReference<Map<String, Object>>() { });
if (this.nextObject == null) {
throw new IllegalStateException("The next parsed object of the Json structure was null");
}
} catch (final Exception e) {
LOG.error("There was a problem initializing the next Object: " + e.getMessage(), e);
throw new RuntimeException("There was a problem initializing the next Object: " + e.getMessage(), e);
}
}
@Override
public boolean hasNext() {
if (!this.isInitialized) {
this.init();
}
return this.nextObject != null;
}
@Override
public Map<String, Object> next() {
// This method will return the current object and initialize the next object so hasNext will always have knowledge of the current state
// Makes sure we're initialized first
if (!this.isInitialized) {
this.init();
}
// Store the current next object for return
final Map<String, Object> currentNextObject = this.nextObject;
// Initialize the next object
this.initNextObject();
return currentNextObject;
}
@Override
public void close() throws IOException {
IOUtils.closeQuietly(this.jsonParser);
IOUtils.closeQuietly(this.inputStream);
}
}
메모리 사용량을 신경 쓰지 않는다면 파일 전체를 읽고 다른 답변에서 언급한 것처럼 하나의 큰 Json으로 해석하는 것이 분명 더 쉬울 것입니다.
이와 같이 InputStream의 toString 메서드를 사용할 수 없다는 지적에 대해서는http://https://stackoverflow.com/a/5445161/1304830 를 참조해 주세요.
제 정답은 다음과 같습니다.
import org.json.JSONObject;
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
...
JSONObject json = new JSONObject(convertStreamToString(url.openStream());
Jackson Databind를 사용하는 경우(어느쪽입니까)Spring디폴트로는 를 사용합니다.HttpMessageConvertersObjectMapper.readTree(InputStream) API를 사용할 수 있습니다.예를들면,
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree(myInputStream);
Jackson을 사용하여 json 입력 스트림을 맵 또는 개체로 변환 http://jackson.codehaus.org/
json을 위한 다른 유용한 라이브러리도 있습니다. 구글에서 json java를 검색할 수 있습니다.
도서관을 이용하다.
Gson을 사용한 Kotlin 버전
응답을 읽으려면 JSON:
val response = BufferedReader(
InputStreamReader(conn.inputStream, "UTF-8")
).use { it.readText() }
응답을 해석하기 위해 Gson을 사용할 수 있습니다.
val model = Gson().fromJson(response, YourModelClass::class.java)
이 예에서는 오브젝트 스트림에서 모든 오브젝트를 읽고 맵 대신 CustomObjects가 필요하다고 가정합니다.
ObjectMapper mapper = new ObjectMapper();
JsonParser parser = mapper.getFactory().createParser( source );
if(parser.nextToken() != JsonToken.START_ARRAY) {
throw new IllegalStateException("Expected an array");
}
while(parser.nextToken() == JsonToken.START_OBJECT) {
// read everything from this START_OBJECT to the matching END_OBJECT
// and return it as a tree model ObjectNode
ObjectNode node = mapper.readTree(parser);
CustomObject custom = mapper.convertValue( node, CustomObject.class );
// do whatever you need to do with this object
System.out.println( "" + custom );
}
parser.close();
이 답변은 잭슨을 사용하여 Json 객체의 어레이를 스트림 해석하고 Json Node를 객체로 변환하는 방법으로 구성되었습니다.
javax.json 사용을 권장합니다.Json 팩토리에서는 가능한 한 상세하지 않은 솔루션:
JsonObject json = Json.createReader(yourInputStream).readObject();
맛있게 드세요!
JSON 파일이 있는 경우 자산 폴더에 파일을 설정하고 이 코드를 사용하여 호출할 수 있습니다.
InputStream in = mResources.getAssets().open("fragrances.json");
// where mResources object from Resources class
{
InputStream is = HTTPClient.get(url);
InputStreamReader reader = new InputStreamReader(is);
JSONTokener tokenizer = new JSONTokener(reader);
JSONObject jsonObject = new JSONObject(tokenizer);
}
언급URL : https://stackoverflow.com/questions/6511880/how-to-parse-a-json-input-stream
'programing' 카테고리의 다른 글
| JSON 로그 파일을 쓰는 형식을 선택하십시오. (0) | 2023.02.08 |
|---|---|
| AngularJS - 컨트롤러에서 모듈 상수 가져오기 (0) | 2023.02.08 |
| 인증된 XMLHttpRequest 후에 브라우저가 인가 헤더를 재사용하지 않는 이유는 무엇입니까? (0) | 2023.02.08 |
| 각도 감시 사이클 또는 다이제스트 사이클이 완료되면 함수를 호출하는 방법 (0) | 2023.02.08 |
| 많은 입력을 데이터베이스화하는 angularjs 방법은 무엇입니까? (0) | 2023.02.08 |