Сериализация Java-объекта с ObjectOutputStream работает один раз, попробовал reset() с обеих сторон
Я использую этот статический класс как способ сериализации объектов в строки перед их отправкой / использованием различными способами. Однако сериализуемые объекты, похоже, корректно сериализуются только один раз. Переменная, начинающаяся с 20 и увеличивающая каждое обновление, достигает только 21, хотя, если я распечатаю ее непосредственно перед сериализацией, значение будет правильным (где-то около 1500).
Прежде чем ответить, обратите внимание, что я использую reset() и writeUnshared(). Я перепробовал почти все, что смог найти в Интернете, но ничего не помогло.
public class InformationInterface {
static ObjectInputStream ois;
static ObjectOutputStream oos;
static ByteArrayOutputStream baos;
public static Object fromString( String s ) throws IOException ,
ClassNotFoundException {
byte [] data = Base64.getDecoder().decode( s );
ois = new ObjectInputStream(
new ByteArrayInputStream( data ) );
Object o = ois.readUnshared();
ois.close();
return o;
}
public static String toString( Serializable o ) throws IOException {
if(baos!=null){
baos.flush();
}
baos = new ByteArrayOutputStream();
baos.reset();
oos = new ObjectOutputStream( baos );
oos.reset();
oos.writeUnshared(o);
oos.flush();
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
}
Я прочитал много постов здесь, утверждая, что ObjectInputStream хранит ссылку на отправленные объекты (хотя я создаю новый каждый раз и сохраняю ссылку только между сериализациями) с помощью writeUnshared () или reset() работает при отправке нескольких объектов, но я не могу кажется, заставить его работать с моей стороны.
Я не понимаю, почему это не работает. Я даже не отправляю несколько объектов одновременно, а просто хочу способ сериализации одного и того же объекта в течение всего срока службы моего сервера. Тем не менее, полученная сериализованная строка based64 не изменяется вообще после получения первого обновления.
Обратите внимание, что я попробовал несколько других способов сделать это, в том числе вставив прямой блок try/catch, создав совершенно новый объект outputstream и вызвав reset прямо там, где я обычно вызывал бы эти статические функции. Я также попытался использовать ObjectOutput и ObjectInput и получил тот же результат.
Кажется, что все решили свою проблему с помощью reset(), ну, это не мой случай. Могу ли я сделать что-то не так в другом месте в моем коде? Поскольку я читаю данные до того, как они будут сериализованы, и могу подтвердить, что на самом деле это должен быть новый объект, прежде чем они будут сериализованы, я сомневаюсь, что проблема очень далека.
Редактировать, просто попробовал другой способ, используя apacheutils, и я получаю точно такие же результаты. Вот новый код с выводом:
public static Object fromString( String s ) throws IOException ,
ClassNotFoundException {
return convertFromBytes(Base64.getDecoder().decode(s));
}
private static byte[] convertToBytes(Serializable object) throws IOException {
ClientInformation client = (ClientInformation)object;
System.out.println(client.hp);
return SerializationUtils.serialize(object);
}
private static Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
return SerializationUtils.deserialize(bytes);
}
public static String toString( Serializable o ) throws IOException {
String s = Base64.getEncoder().encodeToString(convertToBytes(o));
System.out.println(s);
return s;
}
794
rO0ABXNyACBjb20ucjMuZW5kZ2FtZS5DbGllbnRJbmZvcm1hdGlvbj8t7NEouSNIAgAISQACaHBTAAdzbmFrZWlkSQAIc3Bkc2NhbGVMAANhYmN0ABJMamF2YS9sYW5nL1N0cmluZztMAAJpcHEAfgABTAAEbmFtZXEAfgABTAAIcG9zaXRpb250AB9MY29tL2JhZGxvZ2ljL2dkeC9tYXRoL1ZlY3RvcjI7TAAFc3BlZWRxAH4AAnhwAAADGgGkAAAAAXB0ABAvMTI3LjAuMC4xOjQ1Mzk0dAAHYXMzMmRkZHNyAB1jb20uYmFkbG9naWMuZ2R4Lm1hdGguVmVjdG9yMgyu1b5sQZuzAgACRgABeEYAAXl4cAAAAAAAAAAAc3EAfgAGPczMzQAAAAA=
795
rO0ABXNyACBjb20ucjMuZW5kZ2FtZS5DbGllbnRJbmZvcm1hdGlvbj8t7NEouSNIAgAISQACaHBTAAdzbmFrZWlkSQAIc3Bkc2NhbGVMAANhYmN0ABJMamF2YS9sYW5nL1N0cmluZztMAAJpcHEAfgABTAAEbmFtZXEAfgABTAAIcG9zaXRpb250AB9MY29tL2JhZGxvZ2ljL2dkeC9tYXRoL1ZlY3RvcjI7TAAFc3BlZWRxAH4AAnhwAAADGwGkAAAAAXB0ABAvMTI3LjAuMC4xOjQ1Mzk0dAAHYXMzMmRkZHNyAB1jb20uYmFkbG9naWMuZ2R4Lm1hdGguVmVjdG9yMgyu1b5sQZuzAgACRgABeEYAAXl4cAAAAAAAAAAAc3EAfgAGPczMzQAAAAA=
796
rO0ABXNyACBjb20ucjMuZW5kZ2FtZS5DbGllbnRJbmZvcm1hdGlvbj8t7NEouSNIAgAISQACaHBTAAdzbmFrZWlkSQAIc3Bkc2NhbGVMAANhYmN0ABJMamF2YS9sYW5nL1N0cmluZztMAAJpcHEAfgABTAAEbmFtZXEAfgABTAAIcG9zaXRpb250AB9MY29tL2JhZGxvZ2ljL2dkeC9tYXRoL1ZlY3RvcjI7TAAFc3BlZWRxAH4AAnhwAAADHAGkAAAAAXB0ABAvMTI3LjAuMC4xOjQ1Mzk0dAAHYXMzMmRkZHNyAB1jb20uYmFkbG9naWMuZ2R4Lm1hdGguVmVjdG9yMgyu1b5sQZuzAgACRgABeEYAAXl4cAAAAAAAAAAAc3EAfgAGPczMzQAAAAA=
797
rO0ABXNyACBjb20ucjMuZW5kZ2FtZS5DbGllbnRJbmZvcm1hdGlvbj8t7NEouSNIAgAISQACaHBTAAdzbmFrZWlkSQAIc3Bkc2NhbGVMAANhYmN0ABJMamF2YS9sYW5nL1N0cmluZztMAAJpcHEAfgABTAAEbmFtZXEAfgABTAAIcG9zaXRpb250AB9MY29tL2JhZGxvZ2ljL2dkeC9tYXRoL1ZlY3RvcjI7TAAFc3BlZWRxAH4AAnhwAAADHQGkAAAAAXB0ABAvMTI3LjAuMC4xOjQ1Mzk0dAAHYXMzMmRkZHNyAB1jb20uYmFkbG9naWMuZ2R4Lm1hdGguVmVjdG9yMgyu1b5sQZuzAgACRgABeEYAAXl4cAAAAAAAAAAAc3EAfgAGPczMzQAAAAA=
Как видите, сериализованная строка идентична.
1 ответ
Это то, что вы не должны делать мне, к вашему сведению.
Из контекста кода я сделал:
public static void main(String[] args) throws IOException {
ClientInformation ci = new ClientInformation();
// System.out.println(toString(ci));
toString(ci);
ci.hp = 3;
toString(ci);
// System.out.println(toString(ci));
}
@SuppressWarnings("serial")
private static class ClientInformation implements Serializable {
public int hp = 2;
}
Я запустил его из IDE, используя ваш код, и вот результат:
2
rO0ABXNyADduZXRjcmF3bGVyLmZhY3Rvcmllcy5BcHBsaWNhbnRGYWN0b3J5JENsaWVudEluZm9ybWF0aW9uu7p3ca7TTqkCAAFJAAJocHhwAAAAAg==
3
rO0ABXNyADduZXRjcmF3bGVyLmZhY3Rvcmllcy5BcHBsaWNhbnRGYWN0b3J5JENsaWVudEluZm9ybWF0aW9uu7p3ca7TTqkCAAFJAAJocHhwAAAAAw==
Строки не совпадают. Проблема не здесь.