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.processor; 018 019import java.io.*; 020import java.util.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.common.utils.*; 024import org.apache.juneau.http.header.*; 025import org.apache.juneau.http.response.*; 026import org.apache.juneau.httppart.*; 027import org.apache.juneau.marshaller.*; 028import org.apache.juneau.rest.*; 029import org.apache.juneau.rest.util.*; 030import org.apache.juneau.serializer.*; 031 032/** 033 * Response handler for plain-old Java objects. 034 * 035 * <h5 class='section'>See Also:</h5><ul> 036 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a> 037 * </ul> 038 */ 039public class SerializedPojoProcessor implements ResponseProcessor { 040 041 @Override /* ResponseProcessor */ 042 public int process(RestOpSession opSession) throws IOException, NotAcceptable, BasicHttpException { 043 RestRequest req = opSession.getRequest(); 044 RestResponse res = opSession.getResponse(); 045 SerializerMatch sm = res.getSerializerMatch().orElse(null); 046 HttpPartSchema schema = res.getContentSchema().orElse(null); 047 048 Object o = res.getContent(Object.class); 049 050 if (sm != null) { 051 try { 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 if (req.isPlainText()) 062 res.setHeader(ContentType.TEXT_PLAIN); 063 else 064 res.setHeader(ContentType.of(responseType.toString())); 065 066 SerializerSession session = s 067 .createSession() 068 .properties(req.getAttributes().asMap()) 069 .javaMethod(req.getOpContext().getJavaMethod()) 070 .locale(req.getLocale()) 071 .timeZone(req.getTimeZone().orElse(null)) 072 .mediaType(mediaType) 073 .apply(WriterSerializerSession.Builder.class, x -> x.streamCharset(res.getCharset()).useWhitespace(req.isPlainText() ? true : null)) 074 .schema(schema) 075 .debug(req.isDebug() ? true : null) 076 .uriContext(req.getUriContext()) 077 .resolver(req.getVarResolverSession()) 078 .build(); 079 080 for (Map.Entry<String,String> h : session.getResponseHeaders().entrySet()) 081 res.addHeader(h.getKey(), h.getValue()); 082 083 if (! session.isWriterSerializer()) { 084 if (req.isPlainText()) { 085 FinishablePrintWriter w = res.getNegotiatedWriter(); 086 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 087 session.serialize(o, baos); 088 w.write(StringUtils.toSpacedHex(baos.toByteArray())); 089 w.flush(); 090 w.finish(); 091 } else { 092 FinishableServletOutputStream os = res.getNegotiatedOutputStream(); 093 session.serialize(o, os); 094 os.flush(); 095 os.finish(); 096 } 097 } else { 098 FinishablePrintWriter w = res.getNegotiatedWriter(); 099 session.serialize(o, w); 100 w.flush(); 101 w.finish(); 102 } 103 } catch (SerializeException e) { 104 throw new InternalServerError(e); 105 } 106 return FINISHED; 107 } 108 109 if (o == null) 110 return FINISHED; 111 112 throw new NotAcceptable( 113 "Unsupported media-type in request header ''Accept'': ''{0}''\n\tSupported media-types: {1}", 114 req.getHeaderParam("Accept").orElse(""), Json5.of(res.getOpContext().getSerializers().getSupportedMediaTypes()) 115 ); 116 } 117} 118