`

HttpServletResponseWrapper获取jsp内容

    博客分类:
  • html
jsp 
阅读更多
WEB开发中,可能会遇到这样的需求,统一修改页面的某类标签。一种办法是直接修改返回的html页面,但这样的做法太粗糙且无复用性。另一种办法是在控制层修改http的响应内容,那么如何在java代码中获取、修改并返回正确的内容呢。又或者我们只是单纯地想更深入地了解httpServletResponse,请看以下内容。

首先,关于http,我们接触最多的两个接口是HttpServletRequest和HttpServletResponse。记住,它们都是接口。

apache官方文档(http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletResponse.html)是这样描述HttpServletResponse接口的:
扩展于servletResponse接口,在发送响应时提供http定制服务,比如它包含了访问http消息头和cookies的方法。

ServletResponse
servlet容器创建ServletResponse对象并且将其作为参数传递给servlet的服务方法(doGet, doPost等).
通过调用getOutputStream()返回的ServletOutputStream对象实现二进制数据发送。而字符数据的发送,则通过调用getWriter()返回的PrintWriter对象实现。

而已知的HttpServletResponse实现类为HttpServletResponseWrapper
该类可按照开发者意愿被继承,用以适配servlet响应。该类实现了Wrapper或Decorator模式,方法默认按封装的响应对象访问调用。

由此可见,核心部分在于ServletOutputStream对象的处理,也就是HttpServletResponseWrapper如何适配servlet。
public abstract class ServletOutputStream ServletOutputStream extends java.io.OutputStream
提供了发送二进制数据到客户端的输出流。一个servletoutputstream对象通常通过ServletResponse.getOutputStream()方法取回。
我们看到这是一个servlet容器实现的抽象类,它的子类必须实现java.io.OutputStream.write(int)方法。这句很关键,可以说是本次手动实现响应处理的突破口。

总的思路是,利用HttpServletResponseWrapper封装HttpServletResponse,使 HttpServletResponse采用我们自己定义的输入流(OutputStream)。这样,我们就可以通过这个OutputStream得到 目标jsp页面内容。

public void getContent(ServletRequest req, ServletResponse resp,) throws IOException, ServletException{
		ByteArrayOutputStream os =new ByteArrayOutputStream();
		HttpServletResponseWrapper response = new HttpServletResponseWrapper((HttpServletResponse) resp, os);
		//刷新response的输出流, 在某些情况下, 如果不刷新的话, 会导致部分信息还在缓存中, 而没有写入os中
		response.flush();
		String html = new String(os.toByteArray(), "UTF-8");
		resp.getWriter().print(html);
		
		resp.setContentLength(html.getBytes("UTF-8").length);
		resp.setContentType("text/html;charset=UTF-8");
		resp.getWriter().flush();
		
	}


public class HttpServletResponseWrapper extends
		javax.servlet.http.HttpServletResponseWrapper implements Serializable {

	private static final long serialVersionUID = -6723255025479924073L;

	public HttpServletResponseWrapper(HttpServletResponse response,
			OutputStream outputStream) {
		super(response);
		statusCode = 200;
		this.servletOutputStream = new ServletOutputStreamWrapper(outputStream);
	}

	public ServletOutputStream getOutputStream() {
		return servletOutputStream;
	}

	public void setStatus(int code) {
		statusCode = code;
		super.setStatus(code);
	}

	public void sendError(int i, String string) throws IOException {
		statusCode = i;
		super.sendError(i, string);
	}

	public void sendError(int i) throws IOException {
		statusCode = i;
		super.sendError(i);
	}

	public void sendRedirect(String string) throws IOException {
		statusCode = 302;
		super.sendRedirect(string);
	}

	public void setStatus(int code, String msg) {
		statusCode = code;
		super.setStatus(code);
	}

	public int getStatus() {
		return statusCode;
	}

	public void setContentLength(int length) {
		contentLength = length;
		super.setContentLength(length);
	}

	public int getContentLength() {
		return contentLength;
	}

	public void setContentType(String type) {
		contentType = type;
		super.setContentType(type);
	}

	public String getContentType() {
		return contentType;
	}

	public PrintWriter getWriter() throws IOException {
		if (writer == null)
			writer = new PrintWriter(new OutputStreamWriter(
					servletOutputStream, getCharacterEncoding()), true);
		return writer;
	}

	public void addHeader(String name, String value) {
		String header[] = { name, value };
		headers.add(header);
		super.addHeader(name, value);
	}

	public void setHeader(String name, String value) {
		addHeader(name, value);
	}

	public Collection<String[]> getHeaders() {
		return headers;
	}

	public void addCookie(Cookie cookie) {
		cookies.add(cookie);
		super.addCookie(cookie);
	}

	public Collection<Cookie> getCookies() {
		return cookies;
	}

	public void flushBuffer() throws IOException {
		flush();
		super.flushBuffer();
	}

	public void reset() {
		super.reset();
		cookies.clear();
		headers.clear();
		statusCode = 200;
		contentType = null;
		contentLength = 0;
	}

	public void resetBuffer() {
		super.resetBuffer();
	}

	public void flush() throws IOException {
		if (writer != null)
			writer.flush();
		servletOutputStream.flush();
	}

	public String encodeRedirectUrl(String s) {
		return super.encodeRedirectURL(s);
	}

	public String encodeUrl(String s) {
		return super.encodeURL(s);
	}

	private int statusCode;
	private int contentLength;
	private String contentType;
	private final List<String[]> headers = new ArrayList<String[]>();
	private final List<Cookie> cookies = new ArrayList<Cookie>();
	private ServletOutputStream servletOutputStream;
	private PrintWriter writer;
}


public class ServletOutputStreamWrapper extends ServletOutputStream {
	
	public ServletOutputStreamWrapper(OutputStream stream) {
		this.stream = stream;
	}

	public void write(int b) throws IOException {
		stream.write(b);
	}

	public void write(byte b[]) throws IOException {
		stream.write(b);
	}

	public void write(byte b[], int off, int len) throws IOException {
		stream.write(b, off, len);
	}

	private OutputStream stream;
}
分享到:
评论

相关推荐

    用servlet将jsp文件内容转为html

    使用`RequestDispatcher`接口的`include`方法获取JSP页面的内容。 4. 将获取到的JSP内容输出到一个`ByteArrayOutputStream`对象中。 5. 最后,将`ByteArrayOutputStream`中的内容写入到指定的HTML文件中。 #### ...

    jsp生成静态页面的方法

    2. **处理请求并生成内容**:Servlet调用相应的JSP页面,获取动态生成的HTML内容。 3. **保存为静态页面**:将生成的HTML内容写入硬盘上的HTML文件中,形成静态页面。 4. **返回结果**:向客户端发送操作成功的消息...

    解决JSP字符串乱码的过滤器

    由于Filter无法直接修改ServletResponse的编码,我们需要在响应内容发送前,通过`HttpServletResponseWrapper`包装原始响应对象,然后在包装类中重写`getOutputStream()`方法,返回一个自定义的`ServletOutputStream...

    JSP生成静态页面[归类].pdf

    HttpServletResponse rep = new HttpServletResponseWrapper(response) {...}; // 将请求和包装后的响应传递给RequestDispatcher进行处理 rd.include(request, rep); // 将JSP输出的内容写入到HTML文件 pw....

    jsp实现将动态网页转换成静态页面的方法.docx

    ### JSP实现将动态网页转换成...通过上述步骤,我们可以有效地利用JSP技术将动态内容转换为静态页面,从而实现性能优化的目标。这种方法不仅适用于论坛类应用,还可以广泛应用于各类需要频繁访问数据库的Web项目中。

    java网页格式的所有类的说明

    8. **HTTP客户端API**:Java 7引入了`HttpURLConnection`类,Java 11引入了`HttpClient`模块,用于从Java程序中发起HTTP请求,获取网页内容。 9. **DOM和SAX解析器**:Java提供了对XML文档的解析支持,DOM解析器将...

    解决struts2下载异常的jar包 struts2-sunspoter-stream-1.0.jar

    所以在JSP容器通过Response获取输出流之前,前面的流并没有关闭,所以会造成该异常的报出。 本文解决办法: 在前面所说的网络解决办法中,使用的是一种躲避的方式解决该问题,也就是置之不理。 这里提供一个...

    scwcd考试中常用的API

    - **class: HttpServletResponseWrapper**:用于包装HttpServletResponse对象,允许修改响应属性。 ### 3. Filters Filter在Servlet容器中起着拦截器的作用,可以在请求到达目标资源之前或响应发送到客户端之前...

Global site tag (gtag.js) - Google Analytics