SPR-6932 Add option to extract value from single-key models in MappingJacksonJsonView

This commit is contained in:
Rossen Stoyanchev 2011-03-04 14:19:14 +00:00
parent 761a836236
commit 386d8fdaa6
3 changed files with 51 additions and 3 deletions

View File

@ -43,6 +43,7 @@ import org.springframework.web.servlet.view.AbstractView;
*
* @author Jeremy Grelle
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @see org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
* @since 3.0
*/
@ -61,8 +62,10 @@ public class MappingJacksonJsonView extends AbstractView {
private Set<String> renderedAttributes;
private boolean disableCaching = true;
private boolean extractValueFromSingleKeyModel = false;
private boolean disableCaching = true;
/**
* Construct a new {@code JacksonJsonView}, setting the content type to {@code application/json}.
*/
@ -127,6 +130,19 @@ public class MappingJacksonJsonView extends AbstractView {
this.disableCaching = disableCaching;
}
/**
* Set whether to serialize models containing a single attribute as a map or whether to
* extract the single value from the model and serialize it directly.
* The effect of setting this flag is similar to using
* {@code MappingJacksonHttpMessageConverter} with an {@code @ResponseBody}.
* request-handling method.
*
* <p>Default is {@code false}.
*/
public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) {
this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel;
}
@Override
protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
response.setContentType(getContentType());
@ -170,7 +186,7 @@ public class MappingJacksonJsonView extends AbstractView {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
return (this.extractValueFromSingleKeyModel && result.size() == 1) ? result.values().iterator().next() : result;
}
}

View File

@ -194,6 +194,36 @@ public class MappingJacksonJsonViewTest {
validateResult();
}
@Test
public void filterSingleKeyModel() throws Exception {
view.setExtractValueFromSingleKeyModel(true);
Map<String, Object> model = new HashMap<String, Object>();
TestBeanSimple bean = new TestBeanSimple();
model.put("foo", bean);
Object actual = view.filterModel(model);
assertSame(bean, actual);
}
@Test
public void filterTwoKeyModel() throws Exception {
view.setExtractValueFromSingleKeyModel(true);
Map<String, Object> model = new HashMap<String, Object>();
TestBeanSimple bean1 = new TestBeanSimple();
TestBeanSimple bean2 = new TestBeanSimple();
model.put("foo1", bean1);
model.put("foo2", bean2);
Object actual = view.filterModel(model);
assertTrue(actual instanceof Map);
assertSame(bean1, ((Map) actual).get("foo1"));
assertSame(bean2, ((Map) actual).get("foo2"));
}
private void validateResult() throws Exception {
Object jsResult =
jsContext.evaluateString(jsScope, "(" + response.getContentAsString() + ")", "JSON Stream", 1, null);

View File

@ -2610,7 +2610,9 @@ simpleReport.reportDataKey=myBeanData</programlisting>
of framework-specific classes) will be encoded as JSON. For cases where the
contents of the map need to be filtered, users may specify a specific set of
model attributes to encode via the <literal>RenderedAttributes</literal>
property.</para>
property. The <literal>extractValueFromSingleKeyModel</literal> property
may also be used to have the value in single-key models extracted and
serialized directly rather than as a map of model attributes.</para>
<para>JSON mapping can be customized as needed through the use of Jackson's provided
annotations. When further control is needed, a custom