001/* 002 * #%L 003 * HAPI FHIR - Server Framework 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.rest.api.server; 021 022import jakarta.annotation.Nonnull; 023import jakarta.annotation.Nullable; 024 025import java.io.Closeable; 026import java.io.IOException; 027import java.io.OutputStream; 028import java.io.Writer; 029import java.util.List; 030import java.util.Map; 031 032/** 033 * Implementations of this interface represent a response back to the client from the server. It is 034 * conceptually similar to {@link jakarta.servlet.http.HttpServletResponse} but intended to be agnostic 035 * of the server framework being used. 036 * <p> 037 * This class is a bit of an awkward abstraction given the two styles of servers it supports. 038 * Servlets work by writing to a servlet response that is provided as a parameter by the container. JAX-RS 039 * works by returning an object via a method return back to the containing framework. However using it correctly should 040 * make for compatible code across both approaches. 041 * </p> 042 */ 043public interface IRestfulResponse { 044 045 /** 046 * Initiate a new textual response. The Writer returned by this method must be finalized by 047 * calling {@link #commitResponse(Closeable)} later. 048 * <p> 049 * Note that the caller should not close the returned object, but should instead just 050 * return it to {@link #commitResponse(Closeable)} upon successful completion. This is 051 * different from normal Java practice where you would request it in a <code>try with resource</code> 052 * block, since in Servlets you are not actually required to close the writer/stream, and 053 * doing so automatically may prevent you from correctly handling exceptions. 054 * </p> 055 * 056 * @param theStatusCode The HTTP status code. 057 * @param theContentType The HTTP response content type. 058 * @param theCharset The HTTP response charset. 059 * @param theRespondGzip Should the response be GZip encoded? 060 * @return Returns a {@link Writer} that can accept the response body. 061 */ 062 @Nonnull 063 Writer getResponseWriter(int theStatusCode, String theContentType, String theCharset, boolean theRespondGzip) 064 throws IOException; 065 066 /** 067 * Initiate a new binary response. The OutputStream returned by this method must be finalized by 068 * calling {@link #commitResponse(Closeable)} later. This method should only be used for non-textual 069 * responses, for those use {@link #getResponseWriter(int, String, String, boolean)}. 070 * <p> 071 * Note that the caller should not close the returned object, but should instead just 072 * return it to {@link #commitResponse(Closeable)} upon successful completion. This is 073 * different from normal Java practice where you would request it in a <code>try with resource</code> 074 * block, since in Servlets you are not actually required to close the writer/stream, and 075 * doing so automatically may prevent you from correctly handling exceptions. 076 * </p> 077 * 078 * @param theStatusCode The HTTP status code. 079 * @param theContentType The HTTP response content type. 080 * @param theContentLength If known, the number of bytes that will be written. {@literal null} otherwise. 081 * @return Returns an {@link OutputStream} that can accept the response body. 082 */ 083 @Nonnull 084 OutputStream getResponseOutputStream(int theStatusCode, String theContentType, @Nullable Integer theContentLength) 085 throws IOException; 086 087 /** 088 * Finalizes the response streaming using the writer that was returned by calling either 089 * {@link #getResponseWriter(int, String, String, boolean)} or 090 * {@link #getResponseOutputStream(int, String, Integer)}. This method should only be 091 * called if the response writing/streaming actually completed successfully. If an error 092 * occurred you do not need to commit the response. 093 * 094 * @param theWriterOrOutputStream The {@link Writer} or {@link OutputStream} that was returned by this object, or a Writer/OutputStream 095 * which decorates the one returned by this object. 096 * @return If the server style requires a returned response object (i.e. JAX-RS Server), this method 097 * returns that object. If the server style does not require one (i.e. {@link ca.uhn.fhir.rest.server.RestfulServer}), 098 * this method returns {@literal null}. 099 */ 100 Object commitResponse(@Nonnull Closeable theWriterOrOutputStream) throws IOException; 101 102 /** 103 * Adds a response header. This method must be called prior to calling 104 * {@link #getResponseWriter(int, String, String, boolean)} or {@link #getResponseOutputStream(int, String, Integer)}. 105 * 106 * @param headerKey The header name 107 * @param headerValue The header value 108 */ 109 void addHeader(String headerKey, String headerValue); 110 111 /** 112 * Returns the headers added to this response 113 */ 114 Map<String, List<String>> getHeaders(); 115}