Skip to content

Commit b6e20a4

Browse files
committed
Introduced "jsonPrefix" bean property
This change involves a modification of the "writeContent" template method to include the "jsonPrefix" String instead of the "prefixJson" boolean flag. Since said template method has only been introduced in 3.2.2, this change should hopefully not be a problem. Issue: SPR-10567 (cherry picked from commit 28164b4)
1 parent a8adec7 commit b6e20a4

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class MappingJackson2JsonView extends AbstractView {
6565

6666
private JsonEncoding encoding = JsonEncoding.UTF8;
6767

68-
private boolean prefixJson = false;
68+
private String jsonPrefix;
6969

7070
private Boolean prettyPrint;
7171

@@ -123,22 +123,32 @@ public final JsonEncoding getEncoding() {
123123
return this.encoding;
124124
}
125125

126+
/**
127+
* Specify a custom prefix to use for this view's JSON output.
128+
* Default is none.
129+
* @see #setPrefixJson
130+
*/
131+
public void setJsonPrefix(String jsonPrefix) {
132+
this.jsonPrefix = jsonPrefix;
133+
}
134+
126135
/**
127136
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
128137
* Default is {@code false}.
129138
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
130139
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
131140
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
132141
* on the string, the prefix would need to be ignored.
142+
* @see #setJsonPrefix
133143
*/
134144
public void setPrefixJson(boolean prefixJson) {
135-
this.prefixJson = prefixJson;
145+
this.jsonPrefix = "{} && ";
136146
}
137147

138148
/**
139149
* Whether to use the default pretty printer when writing JSON.
140150
* This is a shortcut for setting up an {@code ObjectMapper} as follows:
141-
* <pre>
151+
* <pre class="code">
142152
* ObjectMapper mapper = new ObjectMapper();
143153
* mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
144154
* </pre>
@@ -244,7 +254,7 @@ protected void renderMergedOutputModel(Map<String, Object> model, HttpServletReq
244254

245255
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
246256
Object value = filterModel(model);
247-
writeContent(stream, value, this.prefixJson);
257+
writeContent(stream, value, this.jsonPrefix);
248258
if (this.updateContentLength) {
249259
writeToResponse(response, (ByteArrayOutputStream) stream);
250260
}
@@ -273,11 +283,11 @@ protected Object filterModel(Map<String, Object> model) {
273283
* Write the actual JSON content to the stream.
274284
* @param stream the output stream to use
275285
* @param value the value to be rendered, as returned from {@link #filterModel}
276-
* @param prefixJson whether the JSON output by this view should be prefixed
277-
* with <tt>"{} && "</tt> (as indicated through {@link #setPrefixJson})
286+
* @param jsonPrefix the prefix for this view's JSON output
287+
* (as indicated through {@link #setJsonPrefix}/{@link #setPrefixJson})
278288
* @throws IOException if writing failed
279289
*/
280-
protected void writeContent(OutputStream stream, Object value, boolean prefixJson) throws IOException {
290+
protected void writeContent(OutputStream stream, Object value, String jsonPrefix) throws IOException {
281291
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
282292

283293
// A workaround for JsonGenerators not applying serialization features
@@ -286,8 +296,8 @@ protected void writeContent(OutputStream stream, Object value, boolean prefixJso
286296
generator.useDefaultPrettyPrinter();
287297
}
288298

289-
if (prefixJson) {
290-
generator.writeRaw("{} && ");
299+
if (jsonPrefix != null) {
300+
generator.writeRaw(jsonPrefix);
291301
}
292302
this.objectMapper.writeValue(generator, value);
293303
}

spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJacksonJsonView.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class MappingJacksonJsonView extends AbstractView {
6565

6666
private JsonEncoding encoding = JsonEncoding.UTF8;
6767

68-
private boolean prefixJson = false;
68+
private String jsonPrefix;
6969

7070
private Boolean prettyPrint;
7171

@@ -123,16 +123,26 @@ public final JsonEncoding getEncoding() {
123123
return this.encoding;
124124
}
125125

126+
/**
127+
* Specify a custom prefix to use for this view's JSON output.
128+
* Default is none.
129+
* @see #setPrefixJson
130+
*/
131+
public void setJsonPrefix(String jsonPrefix) {
132+
this.jsonPrefix = jsonPrefix;
133+
}
134+
126135
/**
127136
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
128137
* Default is {@code false}.
129138
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
130139
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
131140
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
132141
* on the string, the prefix would need to be ignored.
142+
* @see #setJsonPrefix
133143
*/
134144
public void setPrefixJson(boolean prefixJson) {
135-
this.prefixJson = prefixJson;
145+
this.jsonPrefix = "{} && ";
136146
}
137147

138148
/**
@@ -244,7 +254,7 @@ protected void renderMergedOutputModel(Map<String, Object> model, HttpServletReq
244254

245255
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
246256
Object value = filterModel(model);
247-
writeContent(stream, value, this.prefixJson);
257+
writeContent(stream, value, this.jsonPrefix);
248258
if (this.updateContentLength) {
249259
writeToResponse(response, (ByteArrayOutputStream) stream);
250260
}
@@ -273,11 +283,11 @@ protected Object filterModel(Map<String, Object> model) {
273283
* Write the actual JSON content to the stream.
274284
* @param stream the output stream to use
275285
* @param value the value to be rendered, as returned from {@link #filterModel}
276-
* @param prefixJson whether the JSON output by this view should be prefixed
277-
* with <tt>"{} && "</tt> (as indicated through {@link #setPrefixJson})
286+
* @param jsonPrefix the prefix for this view's JSON output
287+
* (as indicated through {@link #setJsonPrefix}/{@link #setPrefixJson})
278288
* @throws IOException if writing failed
279289
*/
280-
protected void writeContent(OutputStream stream, Object value, boolean prefixJson) throws IOException {
290+
protected void writeContent(OutputStream stream, Object value, String jsonPrefix) throws IOException {
281291
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
282292

283293
// A workaround for JsonGenerators not applying serialization features
@@ -286,8 +296,8 @@ protected void writeContent(OutputStream stream, Object value, boolean prefixJso
286296
generator.useDefaultPrettyPrinter();
287297
}
288298

289-
if (prefixJson) {
290-
generator.writeRaw("{} && ");
299+
if (jsonPrefix != null) {
300+
generator.writeRaw(jsonPrefix);
291301
}
292302
this.objectMapper.writeValue(generator, value);
293303
}

0 commit comments

Comments
 (0)