寻找使用servletfilter将内容插入响应的示例

我一直在寻找net和stackoverflow的例子,有人使用servletfilter将内容插入到响应中,但只能find捕获/压缩输出和/或更改标头的人员的示例。 我的目标是在所有HTML响应的结束</ body>之前附加一大块HTML。

我正在开发一个解决scheme,扩展HttpServletResponseWrapper使用我自己的PrintWriter,然后覆盖其上的写入方法。 在写入方法中,我存储了最后7个字符,看它是否与closures主体标记相同,然后写入我的HTML块和closures主体标记,然后继续执行文档其余部分的正常写入操作。

我觉得有人已经解决了这个问题,可能比我更优雅。 我将不胜感激任何如何使用servletfilter插入内容到响应的例子。

更新

回应评论,我也试图从http://www.oracle.com/technetwork/java/filters-137243.html实施CharResponseWrapper。 这是我的代码:

PrintWriter out = response.getWriter(); CharResponseWrapper wrappedResponse = new CharResponseWrapper( (HttpServletResponse)response); chain.doFilter(wrappedRequest, wrappedResponse); String s = wrappedResponse.toString(); if (wrappedResponse.getContentType().equals("text/html") && StringUtils.isNotBlank(s)) { CharArrayWriter caw = new CharArrayWriter(); caw.write(s.substring(0, s.indexOf("</body>") - 1)); caw.write("WTF</body></html>"); response.setContentLength(caw.toString().length()); out.write(caw.toString()); } else { out.write(wrappedResponse.toString()); } out.close(); 

我也在包装这个请求,但是这个代码起作用,不应该影响响应。

我使用的代码库在处理响应时调用getOutputStream方法,而不是getWriter,因此包含在其他答案中的示例不起作用。 这是一个更完整的解决scheme,对OutputStream和PrintWriter都起作用,即使错误是正确的,如果作者被访问两次。 这是从很好的例子派生的, 使用JAVAX.SERVLET.FILTER的DUMP REQUEST和RESPONSE 。

 import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class MyFilter implements Filter { private FilterConfig filterConfig = null; private static class ByteArrayServletStream extends ServletOutputStream { ByteArrayOutputStream baos; ByteArrayServletStream(ByteArrayOutputStream baos) { this.baos = baos; } public void write(int param) throws IOException { baos.write(param); } } private static class ByteArrayPrintWriter { private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private PrintWriter pw = new PrintWriter(baos); private ServletOutputStream sos = new ByteArrayServletStream(baos); public PrintWriter getWriter() { return pw; } public ServletOutputStream getStream() { return sos; } byte[] toByteArray() { return baos.toByteArray(); } } public class CharResponseWrapper extends HttpServletResponseWrapper { private ByteArrayPrintWriter output; private boolean usingWriter; public CharResponseWrapper(HttpServletResponse response) { super(response); usingWriter = false; output = new ByteArrayPrintWriter(); } public byte[] getByteArray() { return output.toByteArray(); } @Override public ServletOutputStream getOutputStream() throws IOException { // will error out, if in use if (usingWriter) { super.getOutputStream(); } usingWriter = true; return output.getStream(); } @Override public PrintWriter getWriter() throws IOException { // will error out, if in use if (usingWriter) { super.getWriter(); } usingWriter = true; return output.getWriter(); } public String toString() { return output.toString(); } } public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { filterConfig = null; } public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { CharResponseWrapper wrappedResponse = new CharResponseWrapper( (HttpServletResponse)response); chain.doFilter(request, wrappedResponse); byte[] bytes = wrappedResponse.getByteArray(); if (wrappedResponse.getContentType().contains("text/html")) { String out = new String(bytes); // DO YOUR REPLACEMENTS HERE out = out.replace("</head>", "WTF</head>"); response.getOutputStream().write(out.getBytes()); } else { response.getOutputStream().write(bytes); } } } 

您将需要实现HttpServletResponseWrapper来修改响应。 看到这个文档的filter的基本要求 ,它有一个例子,转换响应,这是比你想要的更多

编辑

我已经尝试了一个简单的Servlet与响应filter,它完美的工作。 该Servlet输出stringTest和响应filter追加到filteredstring,最后当我从浏览器运行我得到的响应Test filtered ,这是你正在尝试实现。

我在Apache Tomcat 7上运行了下面的代码,它没有任何exception。

Servlet的:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Test"); } 

过滤:

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("BEFORE filter"); PrintWriter out = response.getWriter(); CharResponseWrapper responseWrapper = new CharResponseWrapper( (HttpServletResponse) response); chain.doFilter(request, responseWrapper); String servletResponse = new String(responseWrapper.toString()); out.write(servletResponse + " filtered"); // Here you can change the response System.out.println("AFTER filter, original response: " + servletResponse); } 

CharResponseWrapper (正如文章)

 public class CharResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter output; public String toString() { return output.toString(); } public CharResponseWrapper(HttpServletResponse response) { super(response); output = new CharArrayWriter(); } public PrintWriter getWriter() { return new PrintWriter(output); } } 

web.xml中

 <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>/TestServlet</url-pattern> </servlet-mapping> <filter> <filter-name>TestFilter</filter-name> <filter-class>MyFilter</filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/TestServlet/*</url-pattern> </filter-mapping>