@@ -65,7 +65,7 @@ public class MappingJackson2JsonView extends AbstractView {
65
65
66
66
private JsonEncoding encoding = JsonEncoding .UTF8 ;
67
67
68
- private boolean prefixJson = false ;
68
+ private String jsonPrefix ;
69
69
70
70
private Boolean prettyPrint ;
71
71
@@ -123,22 +123,32 @@ public final JsonEncoding getEncoding() {
123
123
return this .encoding ;
124
124
}
125
125
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
+
126
135
/**
127
136
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
128
137
* Default is {@code false}.
129
138
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
130
139
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
131
140
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
132
141
* on the string, the prefix would need to be ignored.
142
+ * @see #setJsonPrefix
133
143
*/
134
144
public void setPrefixJson (boolean prefixJson ) {
135
- this .prefixJson = prefixJson ;
145
+ this .jsonPrefix = "{} && " ;
136
146
}
137
147
138
148
/**
139
149
* Whether to use the default pretty printer when writing JSON.
140
150
* This is a shortcut for setting up an {@code ObjectMapper} as follows:
141
- * <pre>
151
+ * <pre class="code" >
142
152
* ObjectMapper mapper = new ObjectMapper();
143
153
* mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
144
154
* </pre>
@@ -244,7 +254,7 @@ protected void renderMergedOutputModel(Map<String, Object> model, HttpServletReq
244
254
245
255
OutputStream stream = (this .updateContentLength ? createTemporaryOutputStream () : response .getOutputStream ());
246
256
Object value = filterModel (model );
247
- writeContent (stream , value , this .prefixJson );
257
+ writeContent (stream , value , this .jsonPrefix );
248
258
if (this .updateContentLength ) {
249
259
writeToResponse (response , (ByteArrayOutputStream ) stream );
250
260
}
@@ -273,11 +283,11 @@ protected Object filterModel(Map<String, Object> model) {
273
283
* Write the actual JSON content to the stream.
274
284
* @param stream the output stream to use
275
285
* @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})
278
288
* @throws IOException if writing failed
279
289
*/
280
- protected void writeContent (OutputStream stream , Object value , boolean prefixJson ) throws IOException {
290
+ protected void writeContent (OutputStream stream , Object value , String jsonPrefix ) throws IOException {
281
291
JsonGenerator generator = this .objectMapper .getJsonFactory ().createJsonGenerator (stream , this .encoding );
282
292
283
293
// A workaround for JsonGenerators not applying serialization features
@@ -286,8 +296,8 @@ protected void writeContent(OutputStream stream, Object value, boolean prefixJso
286
296
generator .useDefaultPrettyPrinter ();
287
297
}
288
298
289
- if (prefixJson ) {
290
- generator .writeRaw ("{} && " );
299
+ if (jsonPrefix != null ) {
300
+ generator .writeRaw (jsonPrefix );
291
301
}
292
302
this .objectMapper .writeValue (generator , value );
293
303
}
0 commit comments