#java #json
#ява #json #java
Вопрос:
У меня есть несколько типов значений JSON, которые я хочу извлечь из одного сервлета URL. Например, ReadingType1, ReadingType2, ReadingType3 … каждый из них имеет свою собственную структуру.
Однако, согласно моему коду, когда я анализирую строку JSON и преобразую ее в объект Java, я должен указать тип объекта, к которому она будет приведена. Не существует механизма для проверки структуры JSON, чтобы определить, к какому типу объекта следует применить его в первую очередь.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuffer sb = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
}
Gson gson = new Gson();
Reading reading = gson.fromJson(sb.toString(), Reading.class);
}
Обратите внимание, что последняя строка указывает, что тип считывается при преобразовании его в объект.
Как вы проверяете структуру входных данных JSON, прежде чем определять, что это за объект?
Например.
if (JSON has structure1) { reading = gson.fromJson(sb.toString(), ReadingType1.class); }
else if (JSON has structure2) { reading = gson.fromJson(sb.toString(), ReadingType2.class); }
else if (JSON has structure3) { reading = gson.fromJson(sb.toString(), ReadingType3.class); }
Комментарии:
1. Почему бы вам просто не использовать анализатор JSON для чтения типа класса из JSON? Конечно, сначала вам нужно будет включить тип класса в JSON, введите: 1
2. Предпочтительно, чтобы у вас были разные URL-адреса для разных объектов. (Правильное использование Rest). Если нет, то вы могли бы либо внедрить тип класса и протестировать
String.contains ("classtype="ReadingType1"");
, либо использовать блоки try catch
Ответ №1:
Я добавил в свой JSON строковый параметр, в котором указано имя класса.
// sample JSON
{
"factType":"SomeFact",
"someParam":"value"
}
package com.acme.services;
import java.io.IOException;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* service that maps JSON to class
*
* @author gal.nitzan.1
*
*/
@Service
public class MapperService {
private ObjectMapper mapper = new ObjectMapper();
public MapperService() {
}
@SuppressWarnings("rawtypes")
public Class mapToClass(String jsonString) throws IllegalFactPayloadException {
if (jsonString == null || jsonString.length() == 0) {
throw new IllegalFactPayloadException("jsonString can not be null or empty.");
}
Class clazz = null;
ObjectNode node = null;
try {
node = mapper.readValue(jsonString, ObjectNode.class);
}
catch (JsonParseException e) {
throw new IllegalFactPayloadException(e);
}
catch (JsonMappingException e) {
throw new IllegalFactPayloadException(e);
}
catch (IOException e) {
throw new IllegalFactPayloadException(e);
}
if (node.has("factType")) {
try {
clazz = Class.forName("com.acme.entities." node.get("factType").asText());
}
catch (ClassNotFoundException e) {
throw new IllegalFactPayloadException(e);
}
}
else {
throw new IllegalFactPayloadException("jsonString is missing factType attribute.");
}
return clazz;
}
}
HTH,
Gal