diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java index dc99360ca0..ad954015e2 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java @@ -39,7 +39,7 @@ import org.springframework.util.MimeType; /** * A Jackson 2 based {@link MessageConverter} implementation. * - *

Tested against Jackson 2.2 and 2.3; compatible with Jackson 2.0 and higher. + *

Compatible with Jackson 2.1 and higher. * * @author Rossen Stoyanchev * @author Juergen Hoeller @@ -183,18 +183,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter { if (byte[].class.equals(getSerializedPayloadClass())) { ByteArrayOutputStream out = new ByteArrayOutputStream(1024); JsonEncoding encoding = getJsonEncoding(getMimeType(headers)); - - // The following has been deprecated as late as Jackson 2.2 (April 2013); - // preserved for the time being, for Jackson 2.0/2.1 compatibility. - @SuppressWarnings("deprecation") - JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(out, encoding); - - // A workaround for JsonGenerators not applying serialization features - // https://github.com/FasterXML/jackson-databind/issues/12 - if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) { - generator.useDefaultPrettyPrinter(); - } - + JsonGenerator generator = this.objectMapper.getFactory().createGenerator(out, encoding); this.objectMapper.writeValue(generator, payload); payload = out.toByteArray(); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java index 4e65da0e54..ec8f942171 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.java @@ -48,7 +48,7 @@ import org.springframework.util.ClassUtils; *

By default, this converter supports {@code application/json}. This can be overridden by setting the * {@link #setSupportedMediaTypes supportedMediaTypes} property. * - *

Tested against Jackson 2.2 and 2.3; compatible with Jackson 2.0 and higher. + *

Compatible with Jackson 2.1 and higher. * * @author Arjen Poutsma * @author Keith Donald @@ -233,21 +233,10 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv throws IOException, HttpMessageNotWritableException { JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType()); - // The following has been deprecated as late as Jackson 2.2 (April 2013); - // preserved for the time being, for Jackson 2.0/2.1 compatibility. - @SuppressWarnings("deprecation") - JsonGenerator jsonGenerator = - this.objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding); - - // A workaround for JsonGenerators not applying serialization features - // https://github.com/FasterXML/jackson-databind/issues/12 - if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) { - jsonGenerator.useDefaultPrettyPrinter(); - } - + JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding); try { if (this.jsonPrefix != null) { - jsonGenerator.writeRaw(this.jsonPrefix); + generator.writeRaw(this.jsonPrefix); } Class serializationView = null; String jsonpFunction = null; @@ -258,17 +247,17 @@ public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConv jsonpFunction = container.getJsonpFunction(); } if (jsonpFunction != null) { - jsonGenerator.writeRaw(jsonpFunction + "(" ); + generator.writeRaw(jsonpFunction + "("); } if (serializationView != null) { - this.objectMapper.writerWithView(serializationView).writeValue(jsonGenerator, object); + this.objectMapper.writerWithView(serializationView).writeValue(generator, object); } else { - this.objectMapper.writeValue(jsonGenerator, object); + this.objectMapper.writeValue(generator, object); } if (jsonpFunction != null) { - jsonGenerator.writeRaw(");"); - jsonGenerator.flush(); + generator.writeRaw(");"); + generator.flush(); } } catch (JsonProcessingException ex) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java index 2dac3e9c27..b2da237baf 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java @@ -19,7 +19,12 @@ package org.springframework.web.servlet.view.json; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -45,6 +50,8 @@ import org.springframework.web.servlet.view.AbstractView; * will be encoded as JSON. If the model contains only one key, you can have it extracted encoded as JSON * alone via {@link #setExtractValueFromSingleKeyModel}. * + *

Compatible with Jackson 2.1 and higher. + * * @author Jeremy Grelle * @author Arjen Poutsma * @author Rossen Stoyanchev @@ -60,6 +67,9 @@ public class MappingJackson2JsonView extends AbstractView { */ public static final String DEFAULT_CONTENT_TYPE = "application/json"; + /** + * Default content type for JSONP: "application/javascript". + */ public static final String DEFAULT_JSONP_CONTENT_TYPE = "application/javascript"; @@ -71,8 +81,6 @@ public class MappingJackson2JsonView extends AbstractView { private Boolean prettyPrint; - private final List jsonpParameterNames = new ArrayList(Arrays.asList("jsonp", "callback")); - private Set modelKeys; private boolean extractValueFromSingleKeyModel = false; @@ -81,6 +89,8 @@ public class MappingJackson2JsonView extends AbstractView { private boolean updateContentLength = false; + private Set jsonpParameterNames = new LinkedHashSet(Arrays.asList("jsonp", "callback")); + /** * Construct a new {@code MappingJackson2JsonView}, setting the content type to {@code application/json}. @@ -169,23 +179,6 @@ public class MappingJackson2JsonView extends AbstractView { } } - /** - * Set JSONP request parameter names. Each time a request has one of those - * parameters, the resulting JSON will be wrapped into a function named as - * specified by the JSONP request parameter value. - * - *

The parameter names configured by default are "jsonp" and "callback". - * - * @since 4.1 - * @see JSONP Wikipedia article - */ - public void setJsonpParameterNames(Collection jsonpParameters) { - this.jsonpParameterNames.clear(); - if (jsonpParameters != null) { - this.jsonpParameterNames.addAll(jsonpParameters); - } - } - /** * Set the attribute in the model that should be rendered by this view. * When set, all other model attributes will be ignored. @@ -257,6 +250,19 @@ public class MappingJackson2JsonView extends AbstractView { this.updateContentLength = updateContentLength; } + /** + * Set JSONP request parameter names. Each time a request has one of those + * parameters, the resulting JSON will be wrapped into a function named as + * specified by the JSONP request parameter value. + *

The parameter names configured by default are "jsonp" and "callback". + * @since 4.1 + * @see JSONP Wikipedia article + */ + public void setJsonpParameterNames(Set jsonpParameterNames) { + this.jsonpParameterNames = jsonpParameterNames; + } + + @Override protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { setResponseContentType(request, response); @@ -291,10 +297,12 @@ public class MappingJackson2JsonView extends AbstractView { } private String getJsonpParameterValue(HttpServletRequest request) { - for(String name : this.jsonpParameterNames) { - String value = request.getParameter(name); - if (!StringUtils.isEmpty(value)) { - return value; + if (this.jsonpParameterNames != null) { + for (String name : this.jsonpParameterNames) { + String value = request.getParameter(name); + if (!StringUtils.isEmpty(value)) { + return value; + } } } return null; @@ -310,11 +318,10 @@ public class MappingJackson2JsonView extends AbstractView { */ protected Object filterModel(Map model) { Map result = new HashMap(model.size()); - Set renderedAttributes = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet()); + Set modelKeys = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet()); for (Map.Entry entry : model.entrySet()) { - if (!(entry.getValue() instanceof BindingResult) - && renderedAttributes.contains(entry.getKey()) - && !entry.getKey().equals(JsonView.class.getName())) { + if (!(entry.getValue() instanceof BindingResult) && modelKeys.contains(entry.getKey()) && + !entry.getKey().equals(JsonView.class.getName())) { result.put(entry.getKey(), entry.getValue()); } } @@ -332,17 +339,7 @@ public class MappingJackson2JsonView extends AbstractView { protected void writeContent(OutputStream stream, Object value, String jsonPrefix) throws IOException { - // The following has been deprecated as late as Jackson 2.2 (April 2013); - // preserved for the time being, for Jackson 2.0/2.1 compatibility. - @SuppressWarnings("deprecation") - JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding); - - // A workaround for JsonGenerators not applying serialization features - // https://github.com/FasterXML/jackson-databind/issues/12 - if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) { - generator.useDefaultPrettyPrinter(); - } - + JsonGenerator generator = this.objectMapper.getFactory().createGenerator(stream, this.encoding); if (jsonPrefix != null) { generator.writeRaw(jsonPrefix); } @@ -379,4 +376,4 @@ public class MappingJackson2JsonView extends AbstractView { } } -} \ No newline at end of file +} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java index 165af2c55f..8fe4ab5dc5 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java @@ -323,7 +323,7 @@ public class MappingJackson2JsonViewTests { model.put("foo", "bar"); request.addParameter("otherparam", "value"); request.addParameter("custom", "jsonpCallback"); - view.setJsonpParameterNames(Arrays.asList("jsonp", "callback", "custom")); + view.setJsonpParameterNames(new LinkedHashSet(Arrays.asList("jsonp", "callback", "custom"))); view.render(model, request, response); @@ -338,8 +338,14 @@ public class MappingJackson2JsonViewTests { assertEquals("application/json", response.getContentType()); } - public interface MyJacksonView1 {}; - public interface MyJacksonView2 {}; + + public interface MyJacksonView1 { + } + + + public interface MyJacksonView2 { + } + @SuppressWarnings("unused") public static class TestBeanSimple { @@ -378,7 +384,6 @@ public class MappingJackson2JsonViewTests { @JsonSerialize(using=TestBeanSimpleSerializer.class) public static class TestBeanSimpleAnnotated extends TestBeanSimple { - }