10

こんばんは、PrintWriter に書き込まれたデータをクリアする方法を知りたいです。つまり、印刷後に PrintWriter からデータを削除することは可能ですか?

このサーブレットでは、応答にテキストを出力し、 # で示される行で、以前に出力されたデータをすべて削除して、新しいものを出力したいと考えています。

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() を試しましたが、古い印刷テキストが残っています

4

4 に答える 4

10

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());
于 2013-03-23T23:13:20.973 に答える
3

HttpServlteResponse.resetBuffer()バッファリングされたコンテンツをクリアします。しかし、はい、応答が既にクライアントにフラッシュされている場合は、 がスローされIllegalStateExceptionます。部分的な応答がクライアントに送信された後にクリアすることは違法であるためです。

resetBuffer........

void resetBuffer()
ヘッダーまたはステータス コードをクリアせずに、応答内の基になるバッファの内容をクリアします。応答がコミットされている場合、このメソッドは IllegalStateException をスローします。

参考文献:

サーブレットの「Response Already Committed」の原因

于 2013-03-24T07:03:59.890 に答える
0

クライアント接続に対応するPrintWriter実際の値に裏打ちされているため、応答から取得した元の値でそれを行うことはできません。OutputStreamあなたがそこに書いたものは、(いくらかのバッファリングの後)ワイヤーを介してブラウザに直接送られるので、「それを取り戻す」ことはできません。

あなたができることは、あなたのメッセージをいくつかStringBuilderに書いて、それが良いとわかったら、PrintWriter.

このロジックを複数の場所に (透過的に) 適用する場合は、元の応答をHttpServletResponseWrapper「偽物」を返すにラップするフィルターを作成する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);
        }
    }
}
于 2013-03-23T23:05:28.777 に答える
0

最終的にうまくいったのは、データを出力する方法のロジックを変更することでした。

ここに画像の説明を入力

これは、html フォームからのテキストを入力として使用した検索結果を格納する、出力していたデータ構造です。

private final TreeMap<String, ArrayList<SearchResult>> 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();
}

サーブレットの設定を考えると、データ構造のクリアはうまく機能しました。

これが私の主なサーバーレットループロジックです。

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();
    }
}
于 2016-12-15T08:15:37.173 に答える