java 写入后如何清除 PrintWriter 的内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15593086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to clear contents of a PrintWriter after writing
提问by Java Player
Good evening, i want to know how to clear the data written to a PrintWriter, i.e. is it possible to remove the data from a PrintWriter after printing?
晚上好,我想知道如何清除写入 PrintWriter 的数据,即是否可以在打印后从 PrintWriter 中删除数据?
here in this servlet i print some text to the response and at the line denoted by # i want to remove all the previously printed data and print new stuff:
在此 servlet 中,我将一些文本打印到响应中,并在 # 表示的行中删除所有以前打印的数据并打印新内容:
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");
}
}
Note: i tried out.flush() but the old printed text remains
注意:我尝试了 out.flush() 但旧的印刷文本仍然存在
采纳答案by Charles Forsythe
Create an in-memory PrintWriter
using a StringWriter
. You can get the underlying buffer from the StringWriter
and clear it if you need to.
创建一个内存PrintWriter
使用StringWriter
。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());
回答by Ramesh PVK
HttpServlteResponse.resetBuffer()
will clear the buffered content. But yes, if the response is already flushed to the client it will throw IllegalStateException
. Because it is illegal to clear after partial response is sent to the client.
HttpServlteResponse.resetBuffer()
将清除缓冲的内容。但是是的,如果响应已经刷新到客户端,它将抛出IllegalStateException
. 因为在向客户端发送部分响应后清除是非法的。
resetBuffer........
void resetBuffer()
Clears the content of the underlying buffer in the response without clearing headers or status code. If the response has been committed, this method throws an IllegalStateException.
重置缓冲区........
void resetBuffer()
清除响应中底层缓冲区的内容,而不清除标头或状态代码。如果已提交响应,则此方法将引发 IllegalStateException。
References:
参考:
回答by timxor
What ended up working for me was to change the logic of how I was outputting my data.
最终对我有用的是改变我输出数据的逻辑。
This is the data structure I was outputting that stored the results of a search using the text from a html form as input.
这是我输出的数据结构,它存储了使用 html 表单中的文本作为输入的搜索结果。
private final TreeMap<String, ArrayList<SearchResult>> searchResults;
So I was iterating over the contents of this data structure and printing it out to html.
所以我正在迭代这个数据结构的内容并将其打印到 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();
}
Clearing the data structure worked great given my servlet setup.
鉴于我的 servlet 设置,清除数据结构非常有效。
Here was my main serverlet loop logic:
这是我的主要 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();
}
}
回答by Costi Ciudatu
You can't do that with the original PrintWriter
you get from the response, as that's backed by the actual OutputStream
corresponding to the client connection. What you write there goes right to the browser via the wire (after some buffering), so you can't "take it back".
您不能使用PrintWriter
从响应中获得的原始数据来执行此操作,因为这是由OutputStream
与客户端连接对应的实际数据支持的。你在那里写的东西通过线路直接进入浏览器(经过一些缓冲),所以你不能“收回”。
What you can do is write your message in some StringBuilder
and once you know it's good to go, write it to the PrintWriter
.
您可以做的是将您的消息写在一些中StringBuilder
,一旦您知道可以走了,就将其写到PrintWriter
.
If you want this logic to be applied in multiple places (transparently), you can consider writing a filter that wraps the original response in an HttpServletResponseWrapper
which returns a "fake" OutputStream
or PrintWriter
and performs this check prior to actually sending it over the wire.
如果您希望将此逻辑应用于多个地方(透明地),您可以考虑编写一个过滤器,将原始响应包装在一个HttpServletResponseWrapper
返回“假”OutputStream
或PrintWriter
并在实际通过网络发送之前执行此检查的 。
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);
}
}
}