如何在写入后清除PrintWriter的内容

晚上好,我想知道如何清除写入PrintWriter的数据,即打印后是否可以从PrintWriter中删除数据?

在这个servlet中,我将一些文本打印到响应中,并在#i表示的行中删除所有以前打印的数据并打印新内容:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String uName = request.getParameter("uName"); String uPassword = request.getParameter("uPassword"); if (uName .equals("Islam")) { out.println("Valid-Name"); if (uPassword !=null) { if (uPassword .equals("Islam")) { // # clear the writer from any printed data here out.println("Valid-password"); } else { out.println(""); out.println("InValid-password"); } } } else { out.println("InValid-Name"); } } 

注意:我尝试了out.flush()但旧的打印文本仍然存在

使用StringWriter创建内存中的PrintWriter 。 您可以从StringWriter获取底层缓冲区,并在需要时清除它。

 StringWriter sr = new StringWriter(); PrintWriter w = new PrintWriter(sr); w.print("Some stuff"); // Flush writer to ensure that it's not buffering anything w.flush(); // clear stringwriter sr.getBuffer().setLength(0); w.print("New stuff"); // write to Servlet out w.flush(); response.getWriter().print(sr.toString()); 

HttpServlteResponse.resetBuffer()将清除缓冲的内容。 但是,是的,如果响应已经刷新到客户端,它将抛出IllegalStateException 。 因为在将部分响应发送给客户端后清除是非法的。

resetBuffer ……..

void resetBuffer()
清除响应中底层缓冲区的内容,而不清除标头或状态代码。 如果已提交响应,则此方法将抛出IllegalStateException。

参考文献:

Servlet的“响应已经承诺”的原因

您无法使用从响应中获得的原始PrintWriter ,因为它由与客户端连接相对应的实际OutputStream支持。 你在那里写的东西通过电线直接进入浏览器(经过一些缓冲后),所以你不能“收回”。

你可以做的是在一些StringBuilder编写你的消息,一旦你知道它的好处,就把它写到PrintWriter

如果您希望在多个位置(透明地)应用此逻辑,您可以考虑在HttpServletResponseWrapper编写一个包装原始响应的filter,该filter返回“假” OutputStreamPrintWriter并在实际通过线路发送之前执行此检查。

 public class CensorshipFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) response; CensorshipResponseWrapper wrapper = new CensorshipResponseWrapper(httpServletResponse); chain.doFilter(request, wrapper); String output = wrapper.sw.toString(); if ( output.contains("Some forbidden pattern") ) { // your check goes here // throw exception or whatever } else { // write the whole thing httpServletResponse.getWriter().write(output); } } @Override public void destroy() { } static class CensorshipResponseWrapper extends HttpServletResponseWrapper { private final StringWriter sw = new StringWriter(); public CensorshipResponseWrapper(HttpServletResponse response) { super(response); } @Override public ServletOutputStream getOutputStream() throws IOException { // you may also fake the output stream, if some of your servlets use this method return super.getOutputStream(); } @Override public PrintWriter getWriter() throws IOException { return new PrintWriter(sw); } } } 

最终为我工作的是改变我输出数据的逻辑。

在此处输入图像描述

这是我输出的数据结构,它使用html表单中的文本作为输入存储搜索结果。

 private final TreeMap> searchResults; 

所以我在迭代这个数据结构的内容并将其打印到html。

 public void writeSearchResultsToHtml(PrintWriter writer) { try { JSONTreeWriter. writeSearchResultsToHtml(searchResults, writer); } catch (ArithmeticException | IllegalArgumentException | IOException | NoSuchElementException e) { System.err.println("Unable to write the search results builder to JSON to the file html."); } // clear results for next search otherwise // the next search will contain the previous // results, store them in history. searchResults.clear(); } 

鉴于我的servlet设置,清除数据结构非常有用。

这是我的主要serverlet循环逻辑:

 public void startServer() { // seed the database for testing crawler.startCrawl("http://cs.usfca.edu/~cs212/birds/birds.html"); index.toJSON("index.json"); // type of handler that supports sessions ServletContextHandler servletContext = null; // turn on sessions and set context servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS); servletContext.setContextPath("/"); servletContext.addServlet(ViewServlet.class, "/"); // default handler for favicon.ico requests DefaultHandler defaultHandler = new DefaultHandler(); defaultHandler.setServeIcon(true); ContextHandler defaultContext = new ContextHandler("/favicon.ico"); defaultContext.setHandler(defaultHandler); // setup handler order HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[]{defaultContext, servletContext}); openWebBrowser(); // setup jetty server Server server = new Server(portNumber); server.setHandler(handlers); try { server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); } }