001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest.util; 014 015import java.io.ByteArrayOutputStream; 016import java.io.IOException; 017 018import javax.servlet.ServletOutputStream; 019import javax.servlet.WriteListener; 020import javax.servlet.http.*; 021 022/** 023 * Wraps an {@link HttpServletResponse} and caches the output stream in a separate buffer for debugging purposes. 024 */ 025public class CachingHttpServletResponse extends HttpServletResponseWrapper { 026 027 final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 028 final ServletOutputStream os; 029 030 /** 031 * Wraps the specified response inside a {@link CachingHttpServletResponse} if it isn't already. 032 * 033 * @param res The response to wrap. 034 * @return The wrapped request. 035 * @throws IOException Thrown by underlying body stream. 036 */ 037 public static CachingHttpServletResponse wrap(HttpServletResponse res) throws IOException { 038 if (res instanceof CachingHttpServletResponse) 039 return (CachingHttpServletResponse)res; 040 return new CachingHttpServletResponse(res); 041 } 042 043 /** 044 * Constructor. 045 * 046 * @param res The wrapped servlet response. 047 * @throws IOException Thrown by underlying stream. 048 */ 049 protected CachingHttpServletResponse(HttpServletResponse res) throws IOException { 050 super(res); 051 os = res.getOutputStream(); 052 } 053 054 @Override 055 public ServletOutputStream getOutputStream() throws IOException { 056 return new ServletOutputStream() { 057 058 @Override 059 public boolean isReady() { 060 return os.isReady(); 061 } 062 063 @Override 064 public void setWriteListener(WriteListener writeListener) { 065 os.setWriteListener(writeListener); 066 } 067 068 @Override 069 public void write(int b) throws IOException { 070 baos.write(b); 071 os.write(b); 072 } 073 074 @Override 075 public void flush() throws IOException { 076 os.flush(); 077 } 078 079 @Override 080 public void close() throws IOException { 081 os.close(); 082 } 083 }; 084 } 085 086 /** 087 * Returns the body of the servlet response without consuming the stream. 088 * 089 * @return The body of the response. 090 */ 091 public byte[] getBody() { 092 return baos.toByteArray(); 093 } 094}