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 0a52556ca4ea0dd17ca7456b173edd8a73c7f080..2dac3e9c271b870469c4f90d412087fe1b2de773 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 @@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.AbstractView; @@ -61,8 +62,6 @@ public class MappingJackson2JsonView extends AbstractView { public static final String DEFAULT_JSONP_CONTENT_TYPE = "application/javascript"; - public static final String[] DEFAULT_JSONP_PARAMETER_NAMES = {"jsonp", "callback"}; - private ObjectMapper objectMapper = new ObjectMapper(); @@ -72,6 +71,8 @@ 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; @@ -80,8 +81,6 @@ public class MappingJackson2JsonView extends AbstractView { private boolean updateContentLength = false; - private String[] jsonpParameterNames; - /** * Construct a new {@code MappingJackson2JsonView}, setting the content type to {@code application/json}. @@ -89,7 +88,6 @@ public class MappingJackson2JsonView extends AbstractView { public MappingJackson2JsonView() { setContentType(DEFAULT_CONTENT_TYPE); setExposePathVariables(false); - this.jsonpParameterNames = DEFAULT_JSONP_PARAMETER_NAMES; } @@ -171,6 +169,23 @@ 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. @@ -242,21 +257,6 @@ public class MappingJackson2JsonView extends AbstractView { this.updateContentLength = updateContentLength; } - /** - * Set the names of the request parameters recognized as JSONP ones. - * Each time a request has one of those parameters, the resulting JSON will - * be wrapped into a function named as specified by the JSONP parameter value. - * - * Default JSONP parameter names are "jsonp" and "callback". - * - * @since 4.1 - * @see JSONP Wikipedia article - */ - public void setJsonpParameterNames(Collection jsonpParameterNames) { - Assert.isTrue(!CollectionUtils.isEmpty(jsonpParameterNames), "At least one JSONP query parameter name is required"); - this.jsonpParameterNames = jsonpParameterNames.toArray(new String[jsonpParameterNames.size()]); - } - @Override protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { setResponseContentType(request, response); @@ -268,23 +268,13 @@ public class MappingJackson2JsonView extends AbstractView { } } - @Override - protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) { - if (getJsonpParameterValue(request) != null) { - response.setContentType(DEFAULT_JSONP_CONTENT_TYPE); - } - else { - super.setResponseContentType(request, response); - } - } - @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream()); - Class serializationView = (Class)model.get(JsonView.class.getName()); + Class serializationView = (Class) model.get(JsonView.class.getName()); String jsonpParameterValue = getJsonpParameterValue(request); Object value = filterModel(model); if(serializationView != null || jsonpParameterValue != null) { @@ -301,14 +291,13 @@ public class MappingJackson2JsonView extends AbstractView { } private String getJsonpParameterValue(HttpServletRequest request) { - String jsonpParameterValue = null; - for(String jsonpParameterName : this.jsonpParameterNames) { - jsonpParameterValue = request.getParameter(jsonpParameterName); - if(jsonpParameterValue != null) { - break; + for(String name : this.jsonpParameterNames) { + String value = request.getParameter(name); + if (!StringUtils.isEmpty(value)) { + return value; } } - return jsonpParameterValue; + return null; } /** @@ -380,4 +369,14 @@ public class MappingJackson2JsonView extends AbstractView { } } + @Override + protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) { + if (getJsonpParameterValue(request) != null) { + response.setContentType(DEFAULT_JSONP_CONTENT_TYPE); + } + else { + super.setResponseContentType(request, response); + } + } + } \ No newline at end of file