/* * Copyright 2011 E.J.I.E., S.A. * * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»); * Solo podrá usarse esta obra si se respeta la Licencia. * Puede obtenerse una copia de la Licencia en * * http://ec.europa.eu/idabc/eupl.html * * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito, * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL», * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas. * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones * que establece la Licencia. */ package com.ejie.x38.control.method.annotation; import java.io.IOException; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.core.MethodParameter; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.method.support.ModelAndViewContainer; import com.ejie.x38.control.bind.annotation.Json; import com.ejie.x38.json.JsonMixin; /** * * Clase que permite la resolución de vistas en UDA sobreescribiendo la clase de Spring UrlBasedViewResolver * para incluir las siguientes propiedades para el acceso a beans mediante Expression Language ${...}. * - exposeContextBeansAsAttributes : Permite exponer todos los beans del contexto de Spring * - exposedContextBeanNames : Permite exponer los beans del contexto de Spring definidos como parámetros * * @author UDA * */ public class JsonMethodReturnValueHandler implements HandlerMethodReturnValueHandler { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final MediaType DEFAULT_MEDIA_TYPE = new MediaType("application", "json", DEFAULT_CHARSET); private boolean prefixJson = false; public void setPrefixJson(boolean prefixJson) { this.prefixJson = prefixJson; } /** * Converts Json.mixins() to a Map<Class, Class> * * @param jsonFilter Json annotation * @return Map of Target -> Mixin classes */ protected Map<Class<?>, Class<?>> getMixins(Json jsonFilter) { Map<Class<?>, Class<?>> mixins = new HashMap<Class<?>, Class<?>>(); if(jsonFilter != null) { for(JsonMixin jsonMixin : jsonFilter.mixins()) { mixins.put(jsonMixin.target(), jsonMixin.mixin()); } } return mixins; } @Override public void handleReturnValue(Object arg0, MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest nativeWebRequest) throws Exception { // TODO Auto-generated method stub if (methodParameter.getMethod().getAnnotation(Json.class) != null ) { mavContainer.setRequestHandled(true); HttpOutputMessage httpRequest = this.getResponse(nativeWebRequest); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setMixIns(getMixins(methodParameter.getMethod().getAnnotation(Json.class))); ServletOutputStream outputStream = ((ServletServerHttpResponse)httpRequest).getServletResponse().getOutputStream(); JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(outputStream, JsonEncoding.UTF8); if (this.prefixJson) { jsonGenerator.writeRaw("{} && "); } objectMapper.writeValue(jsonGenerator, arg0); outputStream.flush(); outputStream.close(); // this.writeInternal(objectMapper, arg0, httpRequest); } } private void writeInternal(ObjectMapper objectMapper, Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException{ JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType()); JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding); try { if(prefixJson) jsonGenerator.writeRaw("{} && "); objectMapper.writeValue(jsonGenerator, object); } catch(JsonProcessingException ex) { throw new HttpMessageNotWritableException((new StringBuilder("Could not write JSON: ")).append(ex.getMessage()).toString(), ex); } } private JsonEncoding getJsonEncoding(MediaType contentType) { if(contentType != null && contentType.getCharSet() != null) { Charset charset = contentType.getCharSet(); JsonEncoding ajsonencoding[]; int j = (ajsonencoding = JsonEncoding.values()).length; for(int i = 0; i < j; i++) { JsonEncoding encoding = ajsonencoding[i]; if(charset.name().equals(encoding.getJavaName())) return encoding; } } return JsonEncoding.UTF8; } @Override public boolean supportsReturnType(MethodParameter methodParameter) { return methodParameter.getMethod().getAnnotation(Json.class) != null; } // private ServletServerHttpRequest createInputMessage(NativeWebRequest webRequest) // { // return (HttpServletRequest)webRequest.getNativeRequest(HttpServletRequest.class); // return new ServletServerHttpRequest(servletRequest); // } private HttpOutputMessage getResponse(NativeWebRequest webRequest) { HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class); return new ServletServerHttpResponse(servletResponse); } // @Override // public ModelAndView resolveModelAndView(Method handlerMethod, Class handlerType, Object returnValue, ExtendedModelMap implicitModel, NativeWebRequest webRequest) { // // if(handlerMethod.getAnnotation(Json.class) != null) { // // try { // // HttpServletResponse httpResponse = webRequest.getNativeResponse(HttpServletResponse.class); // // httpResponse.setContentType(DEFAULT_MEDIA_TYPE.toString()); // // OutputStream out = httpResponse.getOutputStream(); // // ObjectMapper objectMapper = new ObjectMapper(); // // objectMapper.getSerializationConfig().setMixInAnnotations(getMixins(handlerMethod.getAnnotation(Json.class))); // // JsonGenerator jsonGenerator = // objectMapper.getJsonFactory().createJsonGenerator(out, JsonEncoding.UTF8); // // if (this.prefixJson) { // jsonGenerator.writeRaw("{} && "); // } // // objectMapper.writeValue(jsonGenerator, returnValue); // // out.flush(); // out.close(); // // return null; // // } catch (JsonProcessingException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } // } // // return UNRESOLVED; // } }