有什么办法可以在服务器端捕获生成的动态内容,并将相同的文件或字符串对象提供给servlet。
我们可以使用JSP生成动态内容,但是我们无法访问服务器端生成的动态内容。我们一旦转发容器生成动态内容并将其发送到响应。
我需要访问服务器端生成的动态内容。
任何帮助将不胜感激。
答案 0 :(得分:15)
如果请求是幂等的(例如GET
请求),则只需使用java.net.URL
来获取JSP输出的InputStream。 E.g。
InputStream input = new URL("http://localhost/context/page.jsp").openStream();
如果请求不是幂等的(例如POST
个请求),那么您需要创建一个Filter
wraps ServletResponse
write()
的自定义实现已覆盖五个package mypackage;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CopyResponseFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// NOOP.
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
// Set character encoding for better world domination.
response.setCharacterEncoding("UTF-8");
// Create copy writer.
HttpServletResponse httpResponse = (HttpServletResponse) response;
CopyWriter copyWriter = new CopyWriter(new OutputStreamWriter(
httpResponse.getOutputStream(), httpResponse.getCharacterEncoding()));
// Filter request with response which is wrapped with new writer.
chain.doFilter(request, wrapResponse(httpResponse, copyWriter));
// Store the copy writer afterwards in session so that it's available in next request.
HttpServletRequest httpRequest = (HttpServletRequest) request;
httpRequest.getSession().setAttribute("copyWriter", copyWriter);
}
public void destroy() {
// NOOP.
}
private static HttpServletResponse wrapResponse
(final HttpServletResponse response, final PrintWriter writer)
{
return new HttpServletResponseWrapper(response) {
public PrintWriter getWriter() throws IOException {
return writer;
}
};
}
}
class CopyWriter extends PrintWriter {
StringBuilder copy = new StringBuilder();
public CopyWriter(Writer out) {
super(out);
}
public void write(int c) {
copy.append((char) c); // It is actually a char, not an int.
super.write(c);
super.flush();
}
public void write(char[] chars) {
copy.append(chars);
super.write(chars);
super.flush();
}
public void write(char[] chars, int offset, int length) {
copy.append(chars, offset, length);
super.write(chars, offset, length);
super.flush();
}
public void write(String string) {
copy.append(string);
super.write(string);
super.flush();
}
public void write(String string, int offset, int length) {
copy.append(string, offset, length);
super.write(string, offset, length);
super.flush();
}
public String getCopy() {
return copy.toString();
}
}
方法的PrintWriter
,其中您将输出复制到存储在会话中的某个缓冲区/构建器或本地磁盘文件系统上的临时文件夹中,以便随后可以在后续访问要求。 E.g。
CopyWriter
您可以访问后续请求的任何servlet中的最终输出(请注意,不能在当前请求的任何servlet中访问它,因为它已经太晚了只需访问会话中的CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter");
String outputOfPreviousRequest = copyWriter.getCopy();
url-pattern
请注意,您应该在覆盖感兴趣的JSP页面的/*
上映射此过滤器,因此不会在url-pattern
左右,否则它将在静态文件(css,js,images等)上运行)也包含在同一个JSP中。
另请注意,同一会话中的多个请求会相互覆盖,您可以通过使用正确的Map<URL, CopyWriter>
或其他方式将其存储在会话中来区分这些请求,例如:在{{1}}左右的味道。
希望这有帮助。
答案 1 :(得分:2)
据我了解您的目标,您希望存储生成的内容。虽然我想不出任何理由这样做,但有可能。
您可以使用Filter
并创建HttpServletResponse
的包装,覆盖一些write
方法并捕获将输出到浏览器的所有内容。
编辑:BalusC的回答是你需要的确切扩展,所以我不会详细介绍。
答案 2 :(得分:0)
您需要在服务器端访问相应的servlet,或者您可以编写servlet。
Here是一个关于使用servlet的小教程。
答案 3 :(得分:0)
需要注意的重要一点是,JSP通过JSP编译器编译为servlet(可能会在中途生成java代码),因此您可以在JSP中使用servlet执行任何操作。
关于这个主题的一个侧面说明:你应该知道MVC,一般来说servlet充当控制器,JSP充当View,任何数据结构(java bean等)充当模型。
对于您的问题,您应该在servlet中生成内容/数据 - 这是由对象表示的动态内容,执行您需要执行的任何处理,设置此数据以便JSP可以访问它(在{{3}中)例如),在JSP中为客户端访问和格式化它。
要熟悉,您应该查看request attribute,Story of a Servlet: An Instant Tutorial。