Java RestTemplate response.getBody在put和post请求的4**和5**错误上引发异常,但在get请求上运行良好

Java RestTemplate response.getBody在put和post请求的4**和5**错误上引发异常,但在get请求上运行良好,java,spring,http,resttemplate,Java,Spring,Http,Resttemplate,我正在尝试拦截并记录所有请求响应。要发出请求,我使用的是restemplate.exchange() 当我发出一个GET请求并得到一个4**错误时,我可以调用ClientHttpResponse.getBody()并可以访问响应体,但对于PUT和POST请求ClientHttpResponse.getBody()方法会引发异常 这可能是什么原因造成的?我如何获得POST和PUT请求的响应正文 这就是我提出请求的地方: apiResponse = restTemplate.exchange(url

我正在尝试拦截并记录所有请求响应。要发出请求,我使用的是
restemplate.exchange()

当我发出一个
GET
请求并得到一个
4**
错误时,我可以调用
ClientHttpResponse.getBody(
)并可以访问响应体,但对于
PUT
POST
请求
ClientHttpResponse.getBody()
方法会引发异常

这可能是什么原因造成的?我如何获得
POST
PUT
请求的响应正文

这就是我提出请求的地方:

apiResponse = restTemplate.exchange(url, vCloudRequest.getHttpMethod(), entity, responseType);
这是侦听器中获取异常的部分:

@Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        ClientHttpResponse response = execution.execute(request, body);

        String requestString = new String(body);

        String responseString = new 
// Below line throws exception
String(ByteStreams.toByteArray(response.getBody()), Charset.forName("UTF-8"));
这是堆栈

Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://176.235.57.11/api/admin/org/bd154aaf-2e7c-446d-91be-f0a45138476b/users
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1876)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at org.springframework.http.client.SimpleClientHttpResponse.getBody(SimpleClientHttpResponse.java:85)
    at org.springframework.http.client.BufferingClientHttpResponseWrapper.getBody(BufferingClientHttpResponseWrapper.java:69)
    at roma.api_utils.model.Interceptors.RequestLoggingInterceptor.intercept(RequestLoggingInterceptor.java:39)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
更新:


在调用
response.getStatusCode()
之前调用
response.getBody()
时,它不会抛出
IOException

对于
PUT
POST
,这取决于您的目标资源。如果您的目标资源在
PUT
POST
请求之后没有在响应的主体中添加任何内容,则获得异常是正常的。通常,您知道随
PUT
POST
一起发送的资源,因此您只需检查响应的状态即可知道您的资源是否已创建或修改。您无需再次检查响应正文。

您可以使用以下命令访问拦截器中的响应正文。我做了一个快速的单元测试,以确认它即使在回复为403的帖子上也能正常工作

但是要小心,getBody返回一个InputStream。这意味着你只能读一次。除非使用新的主体提供新的响应,否则您将无法在拦截器外部再次读取相同的流

...
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    final ClientHttpResponse response = execution.execute(request, body);
    final InputStream body = response.getBody();
    return response;
}
...
基础知识:

HttpURLConnection
有两个类似的字段,
errorStream
inputStream
。当我们调用它的
getInputSteam
方法时,它会检查响应是否有错误代码。如果是这样,它会抛出一个
IOException
并记录它-这就是为什么会出现异常。此外,它还将
inputStream
中的内容复制到
errorStream
,因此我们可以通过调用其
getErrorStream
方法来获取其响应体。这正是它的
getBody
方法的作用:

    @Override
    public InputStream getBody() throws IOException {
        InputStream errorStream = this.connection.getErrorStream();
        this.responseStream = 
(errorStream != null ? errorStream : this.connection.getInputStream());
        return this.responseStream;
    }
它首先检查
errorStream
是否为空。如果为true,则返回它。如果为false,则调用
connection.getInputStream()
并返回该值

下面是答案

  • 为什么调用
    response.getStatusCode()
    后调用
    response.getBody()
    不会引发IOException?这是因为
    getStatusCode
    在内部调用
    getInputStream
    。因此,调用
    getBody
    时,
    errorStream
    将不为null
  • 为什么在http方法为GET时不抛出异常? 请参阅方法
    org.springframework.http.client.SimpleBufferingClientHttpRequest#executeInternal
  • @覆盖
    受保护的ClientHttpResponse executeInternal(HttpHeaders头,字节[]缓冲输出)
    抛出IOException{
    addHeaders(this.connection,headers);
    
    //JDK我有一个类似的需求,即记录每个请求和响应。我编写了一个过滤器并连接到过滤器链中

    代码如下所示:

    public class CustomRequestFilter implements Filter {
    
    
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
        //No custom initialisation required
      }
    
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
          FilterChain filterChain) throws IOException, ServletException {
        try {
    
          HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
          HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
    
            Map<String, String> requestMap = this
                .getTypesafeRequestMap(httpServletRequest);
            BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
                httpServletRequest);
            BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
                httpServletResponse);
    
            final StringBuilder logMessage = new StringBuilder(
                "REST Request - ").append("[HTTP METHOD:")
                .append(httpServletRequest.getMethod())
                .append("] [PATH INFO:")
                .append(httpServletRequest.getServletPath())
                .append("] [REQUEST PARAMETERS:").append(requestMap)
                .append("] [REQUEST BODY:")
                .append(bufferedRequest.getRequestBody())
                .append("] [REMOTE ADDRESS:")
                .append(httpServletRequest.getRemoteAddr()).append("]");
            log.info("=======================REQUEST PAYLOAD=================================");
            log.info(bufferedRequest.getRequestBody());
            log.info("========================================================");
            filterChain.doFilter(bufferedRequest, bufferedResponse);
            logMessage.append(" [RESPONSE:")
                .append(bufferedResponse.getContent()).append("]");
            log.info("=======================REST RESPONSE=================================");
            log.info(bufferedResponse.getContent());
            log.info("========================================================");
                 } catch (Exception a) {
          log.error("Error while filtering ", a);
        }
      }
    
      private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
        Map<String, String> typesafeRequestMap = new HashMap<>();
        Enumeration<?> requestParamNames = request.getParameterNames();
        while (requestParamNames.hasMoreElements()) {
          String requestParamName = (String) requestParamNames.nextElement();
          String requestParamValue;
          if ("password".equalsIgnoreCase(requestParamName)) {
            requestParamValue = "********";
          } else {
            requestParamValue = request.getParameter(requestParamName);
          }
          typesafeRequestMap.put(requestParamName, requestParamValue);
        }
        return typesafeRequestMap;
      }
    
      @Override
      public void destroy() {
        //not yet implemented
      }
    
      private static final class BufferedRequestWrapper extends
          HttpServletRequestWrapper {
    
        private ByteArrayInputStream bais = null;
        private ByteArrayOutputStream baos = null;
        private BufferedServletInputStream bsis = null;
        private byte[] buffer = null;
    
        public BufferedRequestWrapper(HttpServletRequest req)
            throws IOException {
          super(req);
          // Read InputStream and store its content in a buffer.
          InputStream is = req.getInputStream();
          this.baos = new ByteArrayOutputStream();
          byte[] buf = new byte[1024];
          int read;
          while ((read = is.read(buf)) > 0) {
            this.baos.write(buf, 0, read);
          }
          this.buffer = this.baos.toByteArray();
        }
    
        @Override
        public ServletInputStream getInputStream() {
          this.bais = new ByteArrayInputStream(this.buffer);
          this.bsis = new BufferedServletInputStream(this.bais);
          return this.bsis;
        }
    
        String getRequestBody() throws IOException {
          BufferedReader reader = new BufferedReader(new InputStreamReader(
              this.getInputStream()));
          String line;
          StringBuilder inputBuffer = new StringBuilder();
          do {
            line = reader.readLine();
            if (null != line) {
              inputBuffer.append(line.trim());
            }
          } while (line != null);
          reader.close();
          return inputBuffer.toString().trim();
        }
    
      }
    
      private static final class BufferedServletInputStream extends
          ServletInputStream {
    
        private ByteArrayInputStream bais;
    
        public BufferedServletInputStream(ByteArrayInputStream bais) {
          this.bais = bais;
        }
    
        @Override
        public int available() {
          return this.bais.available();
        }
    
        @Override
        public int read() {
          return this.bais.read();
        }
    
        @Override
        public int read(byte[] buf, int off, int len) {
          return this.bais.read(buf, off, len);
        }
    
        @Override
        public boolean isFinished() {
          return false;
        }
    
        @Override
        public boolean isReady() {
          return true;
        }
    
        @Override
        public void setReadListener(ReadListener readListener) {
            //No specific readListener changes required
        }
      }
    
      public class TeeServletOutputStream extends ServletOutputStream {
    
        private final TeeOutputStream targetStream;
    
        public TeeServletOutputStream(OutputStream one, OutputStream two) {
          targetStream = new TeeOutputStream(one, two);
        }
    
        @Override
        public void write(int arg0) throws IOException {
          this.targetStream.write(arg0);
        }
    
        @Override
        public void flush() throws IOException {
          super.flush();
          this.targetStream.flush();
        }
    
        @Override
        public void close() throws IOException {
          super.close();
          this.targetStream.close();
        }
    
        @Override
        public boolean isReady() {
          return false;
        }
    
        @Override
        public void setWriteListener(WriteListener writeListener) {
          //not yet implemented
        }
      }
    
      public class BufferedResponseWrapper implements HttpServletResponse {
    
        HttpServletResponse original;
        TeeServletOutputStream tee;
        ByteArrayOutputStream bos;
    
        public BufferedResponseWrapper(HttpServletResponse response) {
          original = response;
        }
    
        public String getContent() {
          return bos.toString();
        }
    
        @Override
        public PrintWriter getWriter() throws IOException {
          return original.getWriter();
        }
    
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
          if (tee == null) {
            bos = new ByteArrayOutputStream();
            tee = new TeeServletOutputStream(original.getOutputStream(),
                bos);
          }
          return tee;
    
        }
    
        @Override
        public String getCharacterEncoding() {
          return original.getCharacterEncoding();
        }
    
        @Override
        public String getContentType() {
          return original.getContentType();
        }
    
        @Override
        public void setCharacterEncoding(String charset) {
          original.setCharacterEncoding(charset);
        }
    
        @Override
        public void setContentLength(int len) {
          original.setContentLength(len);
        }
    
        @Override
        public void setContentLengthLong(long l) {
          original.setContentLengthLong(l);
        }
    
        @Override
        public void setContentType(String type) {
          original.setContentType(type);
        }
    
        @Override
        public void setBufferSize(int size) {
          original.setBufferSize(size);
        }
    
        @Override
        public int getBufferSize() {
          return original.getBufferSize();
        }
    
        @Override
        public void flushBuffer() throws IOException {
          tee.flush();
        }
    
        @Override
        public void resetBuffer() {
          original.resetBuffer();
        }
    
        @Override
        public boolean isCommitted() {
          return original.isCommitted();
        }
    
        @Override
        public void reset() {
          original.reset();
        }
    
        @Override
        public void setLocale(Locale loc) {
          original.setLocale(loc);
        }
    
        @Override
        public Locale getLocale() {
          return original.getLocale();
        }
    
        @Override
        public void addCookie(Cookie cookie) {
          original.addCookie(cookie);
        }
    
        @Override
        public boolean containsHeader(String name) {
          return original.containsHeader(name);
        }
    
        @Override
        public String encodeURL(String url) {
          return original.encodeURL(url);
        }
    
        @Override
        public String encodeRedirectURL(String url) {
          return original.encodeRedirectURL(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public String encodeUrl(String url) {
          return original.encodeUrl(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public String encodeRedirectUrl(String url) {
          return original.encodeRedirectUrl(url);
        }
    
        @Override
        public void sendError(int sc, String msg) throws IOException {
          original.sendError(sc, msg);
        }
    
        @Override
        public void sendError(int sc) throws IOException {
          original.sendError(sc);
        }
    
        @Override
        public void sendRedirect(String location) throws IOException {
          original.sendRedirect(location);
        }
    
        @Override
        public void setDateHeader(String name, long date) {
          original.setDateHeader(name, date);
        }
    
        @Override
        public void addDateHeader(String name, long date) {
          original.addDateHeader(name, date);
        }
    
        @Override
        public void setHeader(String name, String value) {
          original.setHeader(name, value);
        }
    
        @Override
        public void addHeader(String name, String value) {
          original.addHeader(name, value);
        }
    
        @Override
        public void setIntHeader(String name, int value) {
          original.setIntHeader(name, value);
        }
    
        @Override
        public void addIntHeader(String name, int value) {
          original.addIntHeader(name, value);
        }
    
        @Override
        public void setStatus(int sc) {
          original.setStatus(sc);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public void setStatus(int sc, String sm) {
          original.setStatus(sc, sm);
        }
    
        @Override
        public String getHeader(String arg0) {
          return original.getHeader(arg0);
        }
    
        @Override
        public Collection<String> getHeaderNames() {
          return original.getHeaderNames();
        }
    
        @Override
        public Collection<String> getHeaders(String arg0) {
          return original.getHeaders(arg0);
        }
    
        @Override
        public int getStatus() {
          return original.getStatus();
        }
    
      }
    }
    
    公共类CustomRequestFilter实现了过滤器{
    @凌驾
    public void init(FilterConfig FilterConfig)抛出ServletException{
    //无需自定义初始化
    }
    @凌驾
    public void doFilter(ServletRequest ServletRequest,ServletResponse ServletResponse,
    FilterChain FilterChain)抛出IOException、ServletException{
    试一试{
    HttpServletRequest HttpServletRequest=(HttpServletRequest)servletRequest;
    HttpServletResponse HttpServletResponse=(HttpServletResponse)servletResponse;
    Map requestMap=this
    .getTypesafeRequestMap(httpServletRequest);
    BufferedRequestWrapper bufferedRequest=新的BufferedRequestWrapper(
    httpServletRequest);
    BufferedResponseWrapper bufferedResponse=新的BufferedResponseWrapper(
    httpServletResponse);
    最终StringBuilder日志消息=新StringBuilder(
    “REST请求-”。追加(“[HTTP方法:”)
    .append(httpServletRequest.getMethod())
    .append(“][路径信息:”)
    .append(httpServletRequest.getServletPath())
    .append(“][请求参数:”).append(请求映射)
    .append(“][请求正文:”)
    .append(bufferedRequest.getRequestBody())
    .append(“][远程地址:”)
    .append(httpServletRequest.getRemoteAddr()).append(“]”);
    日志信息(“=============================================================================================================”);
    log.info(bufferedRequest.getRequestBody());
    日志信息(“=======================================================================================================”);
    filterChain.doFilter(bufferedRequest,bufferedResponse);
    logMessage.append(“[响应:”)
    .append(bufferedResponse.getContent()).append(“]”);
    日志信息(“===================================================================================================================”);
    log.info(bufferedResponse.getContent());
    日志信息(“=======================================================================================================”);
    }捕获(例外a){
    log.error(“过滤时出错”,a);
    }
    }
    私有映射getTypesafeRequestMap(HttpServletRequest请求){
    Map-typesafeRequestMap=新HashMap();
    枚举requestParamNames=request.getParameterNames();
    while(requestParamNames.hasMoreElements()){
    字符串requestParamName=(字符串)requestParamNames.nextElement();
    字符串值;
    如果(“密码”).equalsIgnoreCase(要求
    
    public class CustomRequestFilter implements Filter {
    
    
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
        //No custom initialisation required
      }
    
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
          FilterChain filterChain) throws IOException, ServletException {
        try {
    
          HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
          HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
    
            Map<String, String> requestMap = this
                .getTypesafeRequestMap(httpServletRequest);
            BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
                httpServletRequest);
            BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
                httpServletResponse);
    
            final StringBuilder logMessage = new StringBuilder(
                "REST Request - ").append("[HTTP METHOD:")
                .append(httpServletRequest.getMethod())
                .append("] [PATH INFO:")
                .append(httpServletRequest.getServletPath())
                .append("] [REQUEST PARAMETERS:").append(requestMap)
                .append("] [REQUEST BODY:")
                .append(bufferedRequest.getRequestBody())
                .append("] [REMOTE ADDRESS:")
                .append(httpServletRequest.getRemoteAddr()).append("]");
            log.info("=======================REQUEST PAYLOAD=================================");
            log.info(bufferedRequest.getRequestBody());
            log.info("========================================================");
            filterChain.doFilter(bufferedRequest, bufferedResponse);
            logMessage.append(" [RESPONSE:")
                .append(bufferedResponse.getContent()).append("]");
            log.info("=======================REST RESPONSE=================================");
            log.info(bufferedResponse.getContent());
            log.info("========================================================");
                 } catch (Exception a) {
          log.error("Error while filtering ", a);
        }
      }
    
      private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
        Map<String, String> typesafeRequestMap = new HashMap<>();
        Enumeration<?> requestParamNames = request.getParameterNames();
        while (requestParamNames.hasMoreElements()) {
          String requestParamName = (String) requestParamNames.nextElement();
          String requestParamValue;
          if ("password".equalsIgnoreCase(requestParamName)) {
            requestParamValue = "********";
          } else {
            requestParamValue = request.getParameter(requestParamName);
          }
          typesafeRequestMap.put(requestParamName, requestParamValue);
        }
        return typesafeRequestMap;
      }
    
      @Override
      public void destroy() {
        //not yet implemented
      }
    
      private static final class BufferedRequestWrapper extends
          HttpServletRequestWrapper {
    
        private ByteArrayInputStream bais = null;
        private ByteArrayOutputStream baos = null;
        private BufferedServletInputStream bsis = null;
        private byte[] buffer = null;
    
        public BufferedRequestWrapper(HttpServletRequest req)
            throws IOException {
          super(req);
          // Read InputStream and store its content in a buffer.
          InputStream is = req.getInputStream();
          this.baos = new ByteArrayOutputStream();
          byte[] buf = new byte[1024];
          int read;
          while ((read = is.read(buf)) > 0) {
            this.baos.write(buf, 0, read);
          }
          this.buffer = this.baos.toByteArray();
        }
    
        @Override
        public ServletInputStream getInputStream() {
          this.bais = new ByteArrayInputStream(this.buffer);
          this.bsis = new BufferedServletInputStream(this.bais);
          return this.bsis;
        }
    
        String getRequestBody() throws IOException {
          BufferedReader reader = new BufferedReader(new InputStreamReader(
              this.getInputStream()));
          String line;
          StringBuilder inputBuffer = new StringBuilder();
          do {
            line = reader.readLine();
            if (null != line) {
              inputBuffer.append(line.trim());
            }
          } while (line != null);
          reader.close();
          return inputBuffer.toString().trim();
        }
    
      }
    
      private static final class BufferedServletInputStream extends
          ServletInputStream {
    
        private ByteArrayInputStream bais;
    
        public BufferedServletInputStream(ByteArrayInputStream bais) {
          this.bais = bais;
        }
    
        @Override
        public int available() {
          return this.bais.available();
        }
    
        @Override
        public int read() {
          return this.bais.read();
        }
    
        @Override
        public int read(byte[] buf, int off, int len) {
          return this.bais.read(buf, off, len);
        }
    
        @Override
        public boolean isFinished() {
          return false;
        }
    
        @Override
        public boolean isReady() {
          return true;
        }
    
        @Override
        public void setReadListener(ReadListener readListener) {
            //No specific readListener changes required
        }
      }
    
      public class TeeServletOutputStream extends ServletOutputStream {
    
        private final TeeOutputStream targetStream;
    
        public TeeServletOutputStream(OutputStream one, OutputStream two) {
          targetStream = new TeeOutputStream(one, two);
        }
    
        @Override
        public void write(int arg0) throws IOException {
          this.targetStream.write(arg0);
        }
    
        @Override
        public void flush() throws IOException {
          super.flush();
          this.targetStream.flush();
        }
    
        @Override
        public void close() throws IOException {
          super.close();
          this.targetStream.close();
        }
    
        @Override
        public boolean isReady() {
          return false;
        }
    
        @Override
        public void setWriteListener(WriteListener writeListener) {
          //not yet implemented
        }
      }
    
      public class BufferedResponseWrapper implements HttpServletResponse {
    
        HttpServletResponse original;
        TeeServletOutputStream tee;
        ByteArrayOutputStream bos;
    
        public BufferedResponseWrapper(HttpServletResponse response) {
          original = response;
        }
    
        public String getContent() {
          return bos.toString();
        }
    
        @Override
        public PrintWriter getWriter() throws IOException {
          return original.getWriter();
        }
    
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
          if (tee == null) {
            bos = new ByteArrayOutputStream();
            tee = new TeeServletOutputStream(original.getOutputStream(),
                bos);
          }
          return tee;
    
        }
    
        @Override
        public String getCharacterEncoding() {
          return original.getCharacterEncoding();
        }
    
        @Override
        public String getContentType() {
          return original.getContentType();
        }
    
        @Override
        public void setCharacterEncoding(String charset) {
          original.setCharacterEncoding(charset);
        }
    
        @Override
        public void setContentLength(int len) {
          original.setContentLength(len);
        }
    
        @Override
        public void setContentLengthLong(long l) {
          original.setContentLengthLong(l);
        }
    
        @Override
        public void setContentType(String type) {
          original.setContentType(type);
        }
    
        @Override
        public void setBufferSize(int size) {
          original.setBufferSize(size);
        }
    
        @Override
        public int getBufferSize() {
          return original.getBufferSize();
        }
    
        @Override
        public void flushBuffer() throws IOException {
          tee.flush();
        }
    
        @Override
        public void resetBuffer() {
          original.resetBuffer();
        }
    
        @Override
        public boolean isCommitted() {
          return original.isCommitted();
        }
    
        @Override
        public void reset() {
          original.reset();
        }
    
        @Override
        public void setLocale(Locale loc) {
          original.setLocale(loc);
        }
    
        @Override
        public Locale getLocale() {
          return original.getLocale();
        }
    
        @Override
        public void addCookie(Cookie cookie) {
          original.addCookie(cookie);
        }
    
        @Override
        public boolean containsHeader(String name) {
          return original.containsHeader(name);
        }
    
        @Override
        public String encodeURL(String url) {
          return original.encodeURL(url);
        }
    
        @Override
        public String encodeRedirectURL(String url) {
          return original.encodeRedirectURL(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public String encodeUrl(String url) {
          return original.encodeUrl(url);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public String encodeRedirectUrl(String url) {
          return original.encodeRedirectUrl(url);
        }
    
        @Override
        public void sendError(int sc, String msg) throws IOException {
          original.sendError(sc, msg);
        }
    
        @Override
        public void sendError(int sc) throws IOException {
          original.sendError(sc);
        }
    
        @Override
        public void sendRedirect(String location) throws IOException {
          original.sendRedirect(location);
        }
    
        @Override
        public void setDateHeader(String name, long date) {
          original.setDateHeader(name, date);
        }
    
        @Override
        public void addDateHeader(String name, long date) {
          original.addDateHeader(name, date);
        }
    
        @Override
        public void setHeader(String name, String value) {
          original.setHeader(name, value);
        }
    
        @Override
        public void addHeader(String name, String value) {
          original.addHeader(name, value);
        }
    
        @Override
        public void setIntHeader(String name, int value) {
          original.setIntHeader(name, value);
        }
    
        @Override
        public void addIntHeader(String name, int value) {
          original.addIntHeader(name, value);
        }
    
        @Override
        public void setStatus(int sc) {
          original.setStatus(sc);
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public void setStatus(int sc, String sm) {
          original.setStatus(sc, sm);
        }
    
        @Override
        public String getHeader(String arg0) {
          return original.getHeader(arg0);
        }
    
        @Override
        public Collection<String> getHeaderNames() {
          return original.getHeaderNames();
        }
    
        @Override
        public Collection<String> getHeaders(String arg0) {
          return original.getHeaders(arg0);
        }
    
        @Override
        public int getStatus() {
          return original.getStatus();
        }
    
      }
    }