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.response; 014 015import static javax.servlet.http.HttpServletResponse.*; 016 017import java.io.*; 018import java.util.*; 019 020import org.apache.juneau.http.*; 021import org.apache.juneau.internal.*; 022import org.apache.juneau.rest.*; 023import org.apache.juneau.serializer.*; 024 025/** 026 * Response handler for POJOs not handled by other handlers. 027 * 028 * <p> 029 * This uses the serializers defined on the response to serialize the POJO. 030 * 031 * <p> 032 * The {@link Serializer} used is based on the <code>Accept</code> header on the request. 033 * 034 * <p> 035 * The <code>Content-Type</code> header is set to the mime-type defined on the selected serializer based on the 036 * <code>produces</code> value passed in through the constructor. 037 * 038 * <h5 class='section'>See Also:</h5> 039 * <ul> 040 * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-rest-server.MethodReturnTypes">Overview > juneau-rest-server > Method Return Types</a> 041 * </ul> 042 */ 043public class DefaultHandler implements ResponseHandler { 044 045 @SuppressWarnings("resource") 046 @Override /* ResponseHandler */ 047 public boolean handle(RestRequest req, RestResponse res, Object output) throws IOException, RestException { 048 SerializerGroup g = res.getSerializers(); 049 String accept = req.getHeaders().getString("Accept", ""); 050 SerializerMatch sm = g.getSerializerMatch(accept); 051 if (sm != null) { 052 Serializer s = sm.getSerializer(); 053 MediaType mediaType = res.getMediaType(); 054 if (mediaType == null) 055 mediaType = sm.getMediaType(); 056 057 MediaType responseType = s.getResponseContentType(); 058 if (responseType == null) 059 responseType = mediaType; 060 061 res.setContentType(responseType.toString()); 062 063 try { 064 RequestProperties p = res.getProperties(); 065 if (req.isPlainText()) { 066 res.setContentType("text/plain"); 067 } 068 p.append("mediaType", mediaType).append("characterEncoding", res.getCharacterEncoding()); 069 070 SerializerSession session = s.createSession(new SerializerSessionArgs(p, req.getJavaMethod(), req.getLocale(), req.getHeaders().getTimeZone(), mediaType, req.getUriContext())); 071 072 for (Map.Entry<String,String> h : session.getResponseHeaders().entrySet()) 073 res.setHeader(h.getKey(), h.getValue()); 074 075 if (! session.isWriterSerializer()) { 076 if (req.isPlainText()) { 077 FinishablePrintWriter w = res.getNegotiatedWriter(); 078 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 079 session.serialize(output, baos); 080 w.write(StringUtils.toSpacedHex(baos.toByteArray())); 081 w.flush(); 082 w.finish(); 083 } else { 084 FinishableServletOutputStream os = res.getNegotiatedOutputStream(); 085 session.serialize(output, os); 086 os.flush(); 087 os.finish(); 088 } 089 } else { 090 FinishablePrintWriter w = res.getNegotiatedWriter(); 091 session.serialize(output, w); 092 w.flush(); 093 w.finish(); 094 } 095 } catch (SerializeException e) { 096 throw new RestException(SC_INTERNAL_SERVER_ERROR, e); 097 } 098 } else { 099 throw new RestException(SC_NOT_ACCEPTABLE, 100 "Unsupported media-type in request header ''Accept'': ''{0}''\n\tSupported media-types: {1}", 101 req.getHeaders().getString("Accept", ""), g.getSupportedMediaTypes() 102 ); 103 } 104 return true; 105 } 106}