Я практикую сохранение и чтение сериализуемых объектов, когда друг сказал мне, что сериализуемые объекты бесполезны в реальной жизни, что мне лучше сосредоточиться на JSON или XML для сериализации моих объектов, когда я столкнулся с такой ситуацией:
Я хочу предварительно загрузить некоторые FileFilters, чтобы использовать их в диалоговом окне JFileChooser, и я хочу, чтобы эти Filefilters имели более сложное поведение, чем просто расширение файла.
Код работает нормально, но я читал, что могут возникнуть проблемы с безопасностью при сохранении исполняемого кода и его чтении позже. Это правда? Можно ли их избежать?
Мне пришлось реализовать свой собственный интерфейс Predicate из-за того, что Predicate не является сериализуемым.
import java.io.File;
import java.io.Serializable;
public interface MyPredicate extends Serializable {
boolean isValid(File file);
}
Это класс, который определяет, как будут устанавливаться фильтры (он называется List, несмотря на то, что внутри используется карта на случай изменения реализации).
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class FileFilterList implements Serializable {
private Map<String, MyPredicate> filters;
public FileFilterList() {
this.filters = new HashMap<>();
}
public FileFilterList addFilter(String string, MyPredicate predicate) {
this.filters.put(string, predicate);
return this;
}
public Iterator<Map.Entry<String, MyPredicate>> getIterator() {
return this.filters.entrySet().iterator();
}
}
В этой маленькой программе я сохраняю список фильтров в файл
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SaveFileFilter {
public static void main(String[] args) throws IOException {
FileFilterList filterList = new FileFilterList();
filterList
.addFilter("txt, Text files", f -> f.isDirectory() || f.getName().endsWith(".txt"))
.addFilter("Big txt, Big txt files (>1Kb)", f -> f.isDirectory() || (f.getName().endsWith(".txt") || f.length() > 1024))
.addFilter("Small txt, Small txt file (<=1Kb)", f -> f.isDirectory() || (f.getName().endsWith(".txt") || f.length() <= 1024));
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("filters.obj"))) {
oos.writeObject(filterList);
} catch (IOException ioe) {
System.err.println("Sorry, there wa a problem saving filters");
ioe.printStackTrace();
throw ioe;
}
}
}
И это будет основная программа, которая получит список предустановленных фильтров файлов:
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
public class FileFilterUse {
public static void main(String[] args) throws IOException, ClassNotFoundException {
JFileChooser fileChooser = new JFileChooser();
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("filters.obj"))) {
FileFilterList filterList = (FileFilterList) ois.readObject();
filterList.getIterator().forEachRemaining(
(entry) -> fileChooser.addChoosableFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return entry.getValue().isValid(f);
}
@Override
public String getDescription() {
return entry.getKey();
}
}));
fileChooser.showOpenDialog(null);
} catch (IOException ioe) {
System.err.println("There was a problem reading filters file");
ioe.printStackTrace();
throw ioe;
} catch (ClassNotFoundException cnf) {
System.err.println("File format is not correct");
cnf.printStackTrace();
throw cnf;
}
}
}
Каждый файл java имеет строку пакета.
Я предполагаю, что невозможно добиться этой сериализации объектов в JSON или XML, не так ли?
Кстати, любые комментарии по поводу кода были бы очень признательны.