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