JSPを使用して動的なページを生成しています。この動的に生成された完全なページをアーカイブとしてファイルに保存します。
JSPでは、すべてがPrintWriter out = response.getWriter();
に書き込まれます
ページの終わりで、クライアントに応答を送信する前に、このページをファイルまたはバッファーに保存して、後で処理できるようにします。
Printwriter
コンテンツを保存またはString
に変換するにはどうすればよいですか?
それは、PrintWriterがどのように構築されて使用されるかによって異なります。
PrintWriterが最初に構築されてから、それに書き込むコードに渡される場合、PrintWriterをデリゲートとして受け取り、呼び出しをデリゲートに転送するWriterのサブクラスを作成できるDecoratorパターンを使用できますが、また、アーカイブできるコンテンツのコピーも保持されます。
public class DecoratedWriter extends Writer
{
private final Writer delegate;
private final StringWriter archive = new StringWriter();
//pass in the original PrintWriter here
public DecoratedWriter( Writer delegate )
{
this.delegate = delegate;
}
public String getForArchive()
{
return this.archive.toString();
}
public void write( char[] cbuf, int off, int len ) throws IOException
{
this.delegate.write( cbuf, off, len );
this.archive.write( cbuf, off, len );
}
public void flush() throws IOException
{
this.delegate.flush();
this.archive.flush();
}
public void close() throws IOException
{
this.delegate.close();
this.archive.close();
}
}
PrintWriter
の出力から文字列を取得するには、コンストラクタを介してStringWriter
をPrintWriter
に渡すことができます。
@Test
public void writerTest(){
StringWriter out = new StringWriter();
PrintWriter writer = new PrintWriter(out);
// use writer, e.g.:
writer.print("ABC");
writer.print("DEF");
writer.flush(); // flush is really optional here, as Writer calls the empty StringWriter.flush
String result = out.toString();
assertEquals("ABCDEF", result);
}
代わりに StringWriter
を使用しないのはなぜですか?これはあなたが必要とするものを提供できるはずだと思います。
だから例えば:
StringWriter strOut = new StringWriter();
...
String output = strOut.toString();
System.out.println(output);
PrintWriter
オブジェクトだけでは取得できません。データをフラッシュし、それ自体のコンテンツは保持しません。これは、文字列全体を取得するために見る必要があるオブジェクトではありません。
Cdcが行っていることと同様の行に沿って、PrintWriter
を拡張してから、この新しいクラスのインスタンスを作成して渡すことができます。
getArchive()
を呼び出して、ライターを介して渡されたデータのコピーを取得します。
public class ArchiveWriter extends PrintWriter {
private StringBuilder data = new StringBuilder();
public ArchiveWriter(Writer out) {
super(out);
}
public ArchiveWriter(Writer out, boolean autoFlush) {
super(out, autoFlush);
}
public ArchiveWriter(OutputStream out) {
super(out);
}
public ArchiveWriter(OutputStream out, boolean autoFlush) {
super(out, autoFlush);
}
public ArchiveWriter(String fileName) throws FileNotFoundException {
super(fileName);
}
public ArchiveWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
super(fileName, csn);
}
public ArchiveWriter(File file) throws FileNotFoundException {
super(file);
}
public ArchiveWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException {
super(file, csn);
}
@Override
public void write(char[] cbuf, int off, int len) {
super.write(cbuf, off,len);
data.append(cbuf, off, len);
}
@Override
public void write(String s, int off, int len) {
super.write(s, off,len);
data.append(s, off, len);
}
public String getArchive() {
return data.toString();
}
}
私が考える最良の方法は、StringBufferなどの他のオブジェクトで応答を準備し、そのコンテンツを応答に送り、その変数に格納されているコンテンツをファイルに保存した後です。