Перемещение данных из сессионного компонента без сохранения состояния в файл - PullRequest
0 голосов
/ 16 июля 2011

У меня есть сессионный компонент, который извлекает данные из базы данных и форматирует их.В ближайшем будущем ему понадобится вызвать утилиту (которая содержит XML-RPC) для пересылки данных, но сейчас мне нужно выполнить скрипт командной строки, который принимает файл в качестве входных данных (т. Е. «Команда -f имя файла»),Мне не очень нравится идея записи файла из сессионного компонента (и позволил ли бы мне это сделать JBoss?), И я пытался открыть URL-адрес сценария CGI, но это кажется излишним.Итак, какой самый чистый и простой способ поместить эти данные в файл, чтобы я мог вызвать команду?

Дополнительная информация:

  • Наш сервер - JBoss, и он не кластеризован.
  • Размер данных может быть значительным, возможно, он содержит 10 000 фрагментов данных в кодировке XML (этоможет быть разбит на более мелкие куски, если это абсолютно необходимо).

TIA, Ilane

1 Ответ

0 голосов
/ 17 июля 2011

Вот относительно простой подход, чтобы поместить ваш контент в файл.

В вашем сессионном компоненте реализуйте бизнес-метод, который выглядит примерно так:

public Object getContent(String fileName, <Other Args>) {
  // Get content
  // write to a byte array
  byte[] content = ......;
  return new ByteArrayFile(content, fileName);
}

Реализация метода должна получить данные (из БД) и сериализовать их в байтовый массив, который затем загружается (вместе с необязательным именем файла) в экземпляр ByteArrayFile и возвращается.

ByteArrayFile - это сериализуемый объект, который реализует метод readResolved , который преобразует массив байтов в локальный файл (используя предоставленное имя или временный файл) и возвращается в вызывающий как java.io.File .

Вот примерная реализация ByteArrayFile :

public class ByteArrayFile implements Serializable {
    protected final byte[] content;
    protected final String fileName;

    /**
     * Creates a new ByteArrayFile
     * @param content The file content
     */
    public ByteArrayFile(byte[] content) {
        this(content, null);
    }

    /**
     * Creates a new ByteArrayFile
     * @param content The file content
     * @param fileName The file name to deserialize as
     */
    public ByteArrayFile(byte[] content, String fileName) {
        super();
        this.content = content;
        this.fileName = fileName;
    }

    /**
     * Returns this object as a resolved file when the object is deserialized.
     * @return
     * @throws ObjectStreamException
     */
    protected Object readResolve() throws ObjectStreamException {
        FileOutputStream fos = null;
        try {
            File f = fileName==null ? File.createTempFile(getClass().getSimpleName(), ".file") : new File(fileName);
            if(!f.canWrite()) {
                throw new Exception("Unable to write to designated file [" + fileName + "]", new Throwable());              
            }
            fos = new FileOutputStream(f);
            fos.write(content);
            fos.close();
            fos = null;
            return f;
        } catch (Exception e) {
            throw new RuntimeException("Failed to readResolve", e);
        } finally {
            try { if(fos!=null) fos.close(); } catch (Exception e) {}
        }
    }
}

Это упрощенный (т.е. не удаленный вызов EJB) пример, демонстрирующий создание ByteArrayFile , его сериализацию и последующее чтение в виде файла:

public static void main(String[] args) {
    ByteArrayFile baf = new ByteArrayFile("Hello World".getBytes());
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(baf);
        oos.flush();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        File file = (File)ois.readObject();
        System.out.println("File:" + file.getAbsolutePath() + "  Size:" + file.length());
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

Вывод был:

Файл: /tmp/ByteArrayFile2790187442947455193.file Размер: 11

По правде говоря, ваш сессионный компонент может напрямую записывать файл. Строгие ограничения EJB не применяются JBoss и существуют для обеспечения гарантий переносимости, которые могут вас не волновать. Однако преимущество вышеуказанного подхода заключается в том, что удаленный клиент может вызывать вызов удаленно, но получать файл локально.

...