如何将PrintWriter转换为String或写入文件?

26

我正在使用JSP生成动态页面,希望将完整的动态生成页面保存到文件中作为存档。

在JSP中,所有内容都是写入PrintWriter out = response.getWriter();

在向客户端发送响应之前,在页面末尾我想要保存这个页面,可以将其保存到文件中或者保存在字符串缓冲区以便以后处理。

如何保存Printwriter的内容或将其转换为String


请检查以下问题的答案:如何从Java Servlet返回JSON对象。 - Raj
谢谢Raj的回复,但这不是我想要的。客户端将看到普通的HTML,但在服务器端,脚本将创建本地副本并写入文件。 - superzoom
可能是重复的问题:如何记录Java Web服务器的响应内容 - BalusC
7个回答

57

要从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);
}

12
StringWriter应该可以提供你所需的功能,为什么不使用它呢?
因此,例如:
StringWriter strOut = new StringWriter();
...
String output = strOut.toString();
System.out.println(output);

因为它不是PrintWriter的子类,所以在我们将其定义为PrintWriter而不是Writer的地方,它不能互换使用。 - Yura

7

这将取决于:PrintWriter是如何构建和使用的。

如果先构建PrintWriter,然后传递给写入它的代码,您可以使用装饰器模式来创建一个Writer子类,将PrintWriter作为委托,并将调用转发到委托,同时还维护内容的副本,以便进行存档。

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();
   }
}

10
Java:永远不要错过写36行代码(几乎)无用功的好时机! - Eric Duminil

1

你不能仅凭 PrintWriter 对象来获取它。它会刷新数据,不会在自身内部保存任何内容。这不是你应该查看以获取整个字符串的对象,


谢谢Navneeth Gopalakrishnan,如果我不能使用Printwriter,那么我有哪些选项可用? 那么响应对象呢?因为所有东西都通过响应发送给客户端! - superzoom
1
你可以将想要写的内容写入 StringWriter 中,最后当一切都完成时,你也可以将其写入响应的 writer 中。这样,你就拥有了你所写的数据,可以用于任何其他目的。 - Navneeth G
当我说写入时,我的意思是将 StringWriter 中的内容刷新到 response.getWriter() - Navneeth G

0

类似于cdc所做的,您可以扩展PrintWriter,然后创建并传递此新类的实例。

调用getArchive()获取通过writer传递的数据的副本。

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();
    }
}

0
这对我很有帮助:获取可转换为SOAP的对象作为XML字符串。
JAXBContext jc = JAXBContext.newInstance(o.getClass());
Marshaller m = jc.createMarshaller();
StringWriter writer = new StringWriter();
m.marshal( o, new PrintWriter(writer) );
return writer.toString();

3
这完全是无稽之谈和胡说八道。 - Glenn Bech
这怎么会是“垃圾”或“无意义”的呢?我不理解。 - Jubz

0
我认为最好的方法是将响应准备在其他对象中,比如StringBuffer,然后将其内容刷新到响应中,在将存储在该变量中的内容保存到文件中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接