【问题标题】:how to convert PrintWriter to String or write to a File?如何将 PrintWriter 转换为字符串或写入文件?
【发布时间】:2012-03-02 20:44:17
【问题描述】:

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

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

在页面末尾,在向客户端发送响应之前,我想将此页面保存在文件中或缓冲区中作为字符串供以后处理。

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

【问题讨论】:

标签: java jsp servlets printwriter


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      为什么不改用StringWriter?我认为这应该能够提供您所需要的。

      例如:

      StringWriter strOut = new StringWriter();
      ...
      String output = strOut.toString();
      System.out.println(output);
      

      【讨论】:

      • 因为它不是 PrintWriter 的子类,所以它在我们输入的地方不能互换被定义为 PrintWriter 而不是 Writer
      【解决方案4】:

      这对我有帮助:获得一个支持 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();
      

      【讨论】:

      • 这绝对是垃圾和废话。
      • 这是怎么回事?我不明白。
      【解决方案5】:

      我认为最好的方法是在 StringBuffer 等其他对象中准备您的响应,并将其内容推送到响应中,然后将该变量中存储的内容保存到文件中。

      【讨论】:

        【解决方案6】:

        这将取决于: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();
           }
        }
        

        【讨论】:

        • Java : 永远不要错过一个写 36 行代码(几乎)没有的好机会!
        【解决方案7】:

        您无法仅使用 PrintWriter 对象获得它。它刷新数据,并且自身不包含任何内容。这不是您应该查看的对象以获取整个字符串,

        【讨论】:

        • 谢谢 Navneeth Gopalakrishnan,如果我不能使用 Printwriter,那么我有什么选择?那么响应对象呢?因为一切都是通过响应客户端!!!
        • 你可以把你想写的东西写到一个StringWriter中,最后当一切都完成后,你也可以把它写给reponse的writer。这样,您就拥有了可用于任何其他目的的数据。
        • 当我的意思是写时,我的意思是将 StringWriter 中的内容也刷新到您的response.getWriter()
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        • 1970-01-01
        • 2012-12-08
        相关资源
        最近更新 更多