001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.http; 017 018import java.io.IOException; 019 020import javax.servlet.http.HttpServletResponse; 021 022import org.apache.log4j.Logger; 023 024import core.tut.pori.utils.JSONFormatter; 025 026/** 027 * 028 * Response object that supports JSON output. 029 * 030 * Note that you MUST use this class if you plan to use JSON output, the ResponseData is one you should use if you need XML output. 031 * 032 */ 033public class JSONResponse extends Response { 034 private static final Logger LOGGER = Logger.getLogger(JSONResponse.class); 035 private JSONResponseData _responseData = null; 036 037 /** 038 * This method replaces the default XML/JAXB output with JSON using GSON annotations 039 * and sets content type to {@value core.tut.pori.http.Definitions#CONTENT_TYPE_JSON}. 040 * These to parameters should be changed for the response if format is changed in the overriding method. 041 * 042 * Additionally this method sets the HTTP basic authentication header if the status is set {@link core.tut.pori.http.Response.Status#UNAUTHORIZED}. 043 * 044 * @param response 045 */ 046 @Override 047 public void writeTo(HttpServletResponse response) { 048 JSONResponseData data = _responseData; 049 if(data == null){ // create new response if one does not already exist 050 data = new DefaultJSONResponse(getMessage(), getMethod(), getService(), getStatus()); 051 }else{ // make sure the details in the response are up to date 052 data._message = getMessage(); 053 data._method = getMethod(); 054 data._service = getService(); 055 data._stat = getStatus(); 056 } 057 058 try { 059 response.setContentType(Definitions.CONTENT_TYPE_JSON); 060 response.setCharacterEncoding(Definitions.ENCODING_UTF8); 061 response.getWriter().write(JSONFormatter.createGsonSerializer().toJson(data)); 062 } catch (IOException ex) { 063 LOGGER.error(ex, ex); 064 setStatus(Status.INTERNAL_SERVER_ERROR); 065 } 066 067 Status stat = getStatus(); 068 if(stat != Status.OK){ // don't change defaults if there is OK status 069 response.setStatus(stat.toStatusCode()); 070 if(stat == Status.UNAUTHORIZED){ 071 setDefaultAuthenticationHeader(response); 072 } 073 } 074 } 075 076 /** 077 * @throws UnsupportedOperationException if data is not of type {@link core.tut.pori.http.JSONResponseData} 078 * @see #setResponseData(JSONResponseData) 079 */ 080 @Override 081 public void setResponseData(ResponseData data) throws UnsupportedOperationException { 082 if(data == null){ 083 setResponseData((JSONResponseData)null); 084 }else if(data instanceof JSONResponseData){ 085 setResponseData((JSONResponseData)data); 086 }else{ 087 throw new UnsupportedOperationException("Unsupported data type: "+data.getClass().toString()); 088 } 089 } 090 091 /** 092 * 093 */ 094 public JSONResponse() { 095 super(); 096 } 097 098 /** 099 * 100 * @param data 101 * @throws UnsupportedOperationException if the given data is not of type JSONResponseData 102 */ 103 public JSONResponse(ResponseData data) throws UnsupportedOperationException { 104 super(); 105 setResponseData(data); 106 } 107 108 /** 109 * 110 * @param data 111 */ 112 public JSONResponse(JSONResponseData data){ 113 _responseData = data; 114 } 115 116 /** 117 * 118 * @param stat 119 * @param message 120 */ 121 public JSONResponse(Status stat, String message) { 122 super(stat, message); 123 } 124 125 /** 126 * 127 * @param stat 128 */ 129 public JSONResponse(Status stat) { 130 super(stat); 131 } 132 133 /** 134 * 135 * @param data 136 */ 137 public void setResponseData(JSONResponseData data){ 138 _responseData = data; 139 } 140 141 /** 142 * default implementation 143 * 144 */ 145 private class DefaultJSONResponse extends JSONResponseData{ 146 /** 147 * 148 * @param message 149 * @param method 150 * @param service 151 * @param status 152 */ 153 public DefaultJSONResponse(String message, String method, String service, Status status){ 154 _message = message; 155 _method = method; 156 _service = service; 157 _stat = status; 158 } 159 } // class DefaultGSONResponse 160}