Я думаю, что проблема в том, что вы не закрываете WRITER или адаптер по умолчанию меняет ваши данные
ошибка указывает, что у вас плохо закрыт JSON, возможно, ваш объект не был сжат правильно или экранирование строки было неверным
это мое предложение, и мои тесты проходят мимо меня
Я создаю JSONFileUtil и использую AutoCloseable. Если вам нужно закрыть поток, то рекомендуется использовать инструкцию try-with-resources ссылка
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
public class JSONFileUtil {
public void save(File file, MyDTO myDto) {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8"))) {
writer.write(new Gson().toJson(myDto));
} catch (Exception e) {
e.printStackTrace();
}
}
public MyDTO load(File file) {
try (InputStreamReader freader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"))) {
JsonReader reader = new JsonReader(freader);
return new Gson().fromJson(reader, MyDTO.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
И MyDTO
import java.util.Date;
public class MyDTO {
public String valueString;
public Long valueLong;
public Date valueDate;
}
и мой тест
import java.io.File;
import java.util.Date;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class JSONFileUtilTest {
@Test
public void saveAndLoad() {
//given:
MyDTO myDTO = new MyDTO();
myDTO.valueString = "aaa";
myDTO.valueLong = 4L;
myDTO.valueDate = new Date(1551427491625L);
File cacheFile = new File("cache" + File.separator + "name.json");
//when:
JSONFileUtil jsonFileUtil = new JSONFileUtil();
jsonFileUtil.save(cacheFile, myDTO);
MyDTO resultMyDto = jsonFileUtil.load(cacheFile);
//then:
assertEquals(myDTO.valueLong, resultMyDto.valueLong); //4
assertEquals(myDTO.valueString, resultMyDto.valueString); // "aaa"
assertEquals(myDTO.valueDate.toString(), resultMyDto.valueDate.toString()); // "Mar 1, 2019 9:04:51 AM" OK
assertNotEquals(myDTO.valueDate.getTime(), resultMyDto.valueDate.getTime()); // it not 1551427491625L but 1551427491000L --> 1551427491625L because the default date format does not store milliseconds
//to store this you need to write your adapter
}
}