/** * Releases the representation and all associated objects like streams, * channels or files which are used to produce its content, transient or * not. This method must be systematically called when the representation is * no longer intended to be used. The framework automatically calls back * this method via its connectors on the server-side when sending responses * with an entity and on the client-side when sending a request with an * entity. By default, it calls the {@link #setAvailable(boolean)} method * with "false" as a value.<br> * <br> * Note that for transient socket-bound representations, calling this method * after consuming the whole content shouldn't prevent the reuse of * underlying socket via persistent connections for example. However, if the * content hasn't been read, or has been partially read, the impact should * be to discard the remaining content and to close the underlying * connections.<br> * <br> * Therefore, if you are not interested in the content, or in the remaining * content, you should first call the {@link #exhaust()} method or if this * could be too costly, you should instead explicitly abort the parent * request and the underlying connections using the {@link Request#abort()} * method or a shortcut one like * {@link org.restlet.resource.ServerResource#abort()} or * {@link Response#abort()}. */ publicvoidrelease() { setAvailable(false); }
/** * Sends the response back to the client. Commits the status, headers and * optional entity and send them over the network. The default * implementation only writes the response entity on the response stream or * channel. Subclasses will probably also copy the response headers and * status. * * @param response * The high-level response. * @throws IOException * if the Response could not be written to the network. */ publicvoidsendResponse(Response response)throws IOException { if (response != null) { // Get the connector service to callback RepresentationresponseEntity= response.getEntity(); ConnectorServiceconnectorService= ConnectorHelper .getConnectorService();
if (connectorService != null) { connectorService.beforeSend(responseEntity); } OutputStreamresponseEntityStream=null; try { writeResponseHead(response); if (responseEntity != null) { responseEntityStream = getResponseEntityStream(); writeResponseBody(responseEntity, responseEntityStream); } } finally { if (responseEntityStream != null) { try { responseEntityStream.flush(); responseEntityStream.close(); } catch (IOException ioe) { // The stream was probably already closed by the // connector. Probably OK, low message priority. getLogger().log(Level.FINE, "Exception while flushing and closing the entity stream.", ioe); } } if (responseEntity != null) { responseEntity.release(); } if (connectorService != null) { connectorService.afterSend(responseEntity); } } } }