Страницы

Поиск по вопросам

воскресенье, 9 февраля 2020 г.

Сериализация сложного JAVA объекта в JSON

#java #json #сериализация


Добрый день подскажите как сериализовать в JSON объект Files? Используя метод toJsonString
сериализуются только поле nameDirectory, а поле pool выводится в виде хеша?

import org.json.simple.JSONValue;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class Files {

    public Map pool;

    public String nameDirectory;

    public String toJsonString(){
        JSONObject JSobj = new JSONObject(pool);
        JSobj.toJSONString();
    }
}

public class File {
    String PathFile;
    ArrayList Records;
    boolean PutInEnd;
}

public class Record {

    private String recordname;
    private String status;
    private int countExecution;
}

    


Ответы

Ответ 1



Для таких целей есть специальные библиотеки - Jackson и Gson. import java.io.File; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; class Record { // Поле name и так находится в Record, // называть его recordname - это лишнее private String name; private String status; private int executionCount; public Record() {} public Record(String name, String status, int executionCount) { setName(name); setStatus(status); setExecutionCount(executionCount); } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setStatus(String status) { this.status = status; } public String getStatus() { return status; } public void setExecutionCount(int executionCount) { this.executionCount = executionCount; } public int getExecutionCount() { return executionCount; } } // Плохая идея использовать имена классов // входящих в стандартную библиотеку class SomeFile { private String path; // Имена полей должны начинаться со строчной буквы private List records; private boolean putInEnd; public SomeFile() { records = new ArrayList<>(); } public SomeFile(String path, boolean putInEnd) { this(); setPath(path); setPutInEnd(putInEnd); } public void setPath(String path) { this.path = path; } public String getPath() { return path; } public void setPutInEnd(boolean putInEnd) { this.putInEnd = putInEnd; } public void addRecord(Record record) { records.add(record); } public List getRecords() { return records; } } class SomeFiles { private String name; private Map pool; public SomeFiles() { pool = new HashMap<>(); } public SomeFiles(String name) { this(); setName(name); } public void setName(String name) { this.name = name; } public String getName() { return name; } public void putSomeFile(String name, SomeFile someFile) { pool.put(name, someFile); } public Map getPool() { return pool; } } public class App { public static void main(String[] args) { SomeFile f = new SomeFile("/root/secret.txt", false); f.addRecord(new Record("Some Record", "Some status", 42)); f.addRecord(new Record("Another Record", "Same status", 0)); SomeFiles sf = new SomeFiles("Some Files"); sf.putSomeFile("Some File", f); ObjectMapper mapper = new ObjectMapper(); // Для вывода с отступами mapper.enable(SerializationFeature.INDENT_OUTPUT); try { // Здесь происходит самая главная магия mapper.writeValue(new File("some_files.json"), sf); } catch(JsonGenerationException exc) { exc.printStackTrace(); } catch(JsonMappingException exc) { exc.printStackTrace(); } catch(IOException exc) { exc.printStackTrace(); } } } Получится такое: { "name" : "Some Files", "pool" : { "Some File" : { "path" : "/root/secret.txt", "records" : [ { "name" : "Some Record", "status" : "Some status", "executionCount" : 42 }, { "name" : "Another Record", "status" : "Same status", "executionCount" : 0 } ] } } }

Ответ 2



У вас 2 проблемы: Сериализация Map Сериализация File Если с первой более-менее все понятно - в рамках Gson решается приблизительно так: Map myMap; Type typeOfMap = new TypeToken>() { }.getType(); Gson gson = new GsonBuilder().create(); String json = gson.toJson(myMap, typeOfMap); Вторая проблема более концептуальная что-ли. Никто кроме вас не понимает, что вы имеете ввиду под сериализацией объекта типа File: или вы захотите просто сериализовать имя файла или имя файла включая полный путь или универсальный URI или же вообще содержимое файла. На этот вопрос кроме вас никто не ответит. Чтобы оформить свое отношение к сериализации объекта типа File вам нужно написать свой собственный сериалайзер - в терминах GSon это выглядит примерно так: public class MyFileAdapter implements JsonSerializer { @Override public JsonElement serialize(File src, Type typeOfSrc, JsonSerializationContext context) { //blah-blah } } } Далее надо известить Gson о том, что отныне объекты типа File будут обрабатываться вашим адаптером: GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(File.class, new MyFileAdapter());

Комментариев нет:

Отправить комментарий