Skip to content

Commit 4de62e7

Browse files
committed
jackson: support raw string as json response fix #618
1 parent 93edd99 commit 4de62e7

File tree

6 files changed

+176
-27
lines changed

6 files changed

+176
-27
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.jooby.issues;
2+
3+
import org.jooby.json.Jackson;
4+
import org.jooby.test.ServerFeature;
5+
import org.junit.Test;
6+
7+
import com.google.common.collect.ImmutableMap;
8+
9+
public class Issue618 extends ServerFeature {
10+
11+
{
12+
use(new Jackson().raw());
13+
14+
get("/618", () -> "{\"raw\":\"json\"}");
15+
16+
get("/618/obj", () -> ImmutableMap.of("raw", "json"));
17+
}
18+
19+
@Test
20+
public void rawJsonString() throws Exception {
21+
request()
22+
.get("/618")
23+
.expect("{\"raw\":\"json\"}")
24+
.header("content-type", "application/json;charset=utf-8");
25+
26+
request()
27+
.get("/618/obj")
28+
.expect("{\"raw\":\"json\"}")
29+
.header("content-type", "application/json;charset=utf-8");
30+
}
31+
}

jooby-jackson/src/main/java/org/jooby/json/Jackson.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ public PostConfigurer(final ObjectMapper mapper, final Set<Module> jacksonModule
137137

138138
private List<Consumer<Multibinder<Module>>> modules = new ArrayList<>();
139139

140+
private boolean raw;
141+
140142
/**
141143
* Creates a new {@link Jackson} module and use the provided {@link ObjectMapper} instance.
142144
*
@@ -209,6 +211,24 @@ public Jackson module(final Class<? extends Module> module) {
209211
return this;
210212
}
211213

214+
/**
215+
* Add support raw string json responses:
216+
*
217+
* <pre>{@code
218+
* {
219+
* get("/raw", () -> {
220+
* return "{\"raw\": \"json\"}";
221+
* });
222+
* }
223+
* }</pre>
224+
*
225+
* @return This module.
226+
*/
227+
public Jackson raw() {
228+
raw = true;
229+
return this;
230+
}
231+
212232
@Override
213233
public void configure(final Env env, final Config config, final Binder binder) {
214234
// provided or default mapper.
@@ -242,7 +262,9 @@ public void configure(final Env env, final Config config, final Binder binder) {
242262

243263
// json parser & renderer
244264
JacksonParser parser = new JacksonParser(mapper, type);
245-
JacksonRenderer renderer = new JacksonRenderer(mapper, type);
265+
JacksonRenderer renderer = raw
266+
? new JacksonRawRenderer(mapper, type)
267+
: new JacksonRenderer(mapper, type);
246268

247269
Multibinder.newSetBinder(binder, Renderer.class)
248270
.addBinding()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.jooby.json;
20+
21+
import org.jooby.MediaType;
22+
import org.jooby.Renderer;
23+
24+
import com.fasterxml.jackson.databind.ObjectMapper;
25+
26+
abstract class JacksonBaseRenderer implements Renderer {
27+
28+
protected final ObjectMapper mapper;
29+
30+
protected final MediaType type;
31+
32+
public JacksonBaseRenderer(final ObjectMapper mapper, final MediaType type) {
33+
this.mapper = mapper;
34+
this.type = type;
35+
}
36+
37+
@Override
38+
public void render(final Object value, final Context ctx) throws Exception {
39+
if (ctx.accepts(type) && mapper.canSerialize(value.getClass())) {
40+
ctx.type(type);
41+
renderValue(value, ctx);
42+
}
43+
}
44+
45+
protected abstract void renderValue(Object value, Context ctx) throws Exception;
46+
47+
@Override
48+
public String name() {
49+
return "json";
50+
}
51+
52+
@Override
53+
public String toString() {
54+
return name();
55+
}
56+
57+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.jooby.json;
20+
21+
import org.jooby.MediaType;
22+
23+
import com.fasterxml.jackson.databind.ObjectMapper;
24+
25+
class JacksonRawRenderer extends JacksonRenderer {
26+
27+
public JacksonRawRenderer(final ObjectMapper mapper, final MediaType type) {
28+
super(mapper, type);
29+
}
30+
31+
@Override
32+
protected void renderValue(final Object value, final Context ctx) throws Exception {
33+
if (value instanceof CharSequence) {
34+
ctx.send(value.toString());
35+
} else {
36+
super.renderValue(value, ctx);
37+
}
38+
}
39+
40+
}

jooby-jackson/src/main/java/org/jooby/json/JacksonRenderer.java

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,21 @@
1919
package org.jooby.json;
2020

2121
import org.jooby.MediaType;
22-
import org.jooby.Renderer;
2322

2423
import com.fasterxml.jackson.databind.ObjectMapper;
2524

26-
class JacksonRenderer implements Renderer {
27-
28-
private ObjectMapper mapper;
29-
30-
private MediaType type;
25+
class JacksonRenderer extends JacksonBaseRenderer {
3126

3227
public JacksonRenderer(final ObjectMapper mapper, final MediaType type) {
33-
this.mapper = mapper;
34-
this.type = type;
35-
}
36-
37-
@Override
38-
public void render(final Object value, final Context ctx) throws Exception {
39-
if (ctx.accepts(type) && mapper.canSerialize(value.getClass())) {
40-
ctx.type(type);
41-
// use UTF-8 and get byte version
42-
byte[] bytes = mapper.writeValueAsBytes(value);
43-
ctx.length(bytes.length)
44-
.send(bytes);
45-
}
46-
}
47-
48-
@Override
49-
public String name() {
50-
return "json";
28+
super(mapper, type);
5129
}
5230

5331
@Override
54-
public String toString() {
55-
return name();
32+
protected void renderValue(final Object value, final Context ctx) throws Exception {
33+
// use UTF-8 and get byte version
34+
byte[] bytes = mapper.writeValueAsBytes(value);
35+
ctx.length(bytes.length)
36+
.send(bytes);
5637
}
5738

5839
}

jooby-spec/src/main/java/org/jooby/internal/spec/TypeFromDoc.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
119
package org.jooby.internal.spec;
220

321
import java.lang.reflect.Type;

0 commit comments

Comments
 (0)