I’m building REST service on Jersey
and using Jackson
to produce JSON from java classes of my model. Model with absolutely simple values, I think this is the most typical case. But I get strange result:
[{"name":"Nick","role":"admin","age":"32","rating":47}]
My expecting result:
[{"name":"Nick","role":"admin","age":"32","rating":47}]
My source values of fields does NOT contains any special characters. These are simple words.
There’re my Java classes. Entity:
public class User { private String name; private String role; private String age; private Integer rating;
Class of rest service:
@ServiceConfig(contextName = "myContext") @Path("/myrest") public class MyRestService { private static final String JSON_CONTENT_TYPE = MediaType.APPLICATION_JSON + ";charset=UTF-8"; @Context protected HttpServletResponse response; @GET @Path("/users") @OpenTransaction @Produces({MediaType.APPLICATION_JSON}) public String findUsers(@QueryParam("department") String department) { response.setContentType(JSON_CONTENT_TYPE); PDTResponse.status(response).sendStatus(Response.Status.OK.getStatusCode()); List<User> users = new ArrayList<>(); users.add(new User("Nick", "admin", "32", 47)); String jsonInString; ObjectMapper mapper = new ObjectMapper(); try { jsonInString = mapper.writeValueAsString(users); } catch (JsonProcessingException ex) { jsonInString = "thrown exception: " + ex.getMessage(); } return jsonInString; }
I’ve tried to use annotation @JsonRawValue
for string properties:
@JsonRawValue private String name;
But result in this case was:
[{"name":Nick,"role":admin,"age":32,"rating":47}]
And I expect:
[{"name":"Nick","role":"admin","age":"32","rating":47}]
It’s obvious that Jackson somehow escapes the quotes in result json of response. But why does it do it, and most importantly how to avoid that? By themselves they are just strings! Without any quotes or special characters.
I use Java 7
and Jackson 2.6.1
. And Postman
to test result.
Any ideas for fix of my problem?
Advertisement
Answer
Looks like you are over complicating your JAX-RS resource class.
To use Jackson as a JSON provider for Jersey 2.x, you don’t need to create an ObjectMapper
instance like that. There’s a better way to achieve it. Keep reading for more details.
Adding Jackson module dependencies
To use Jackson 2.x as your JSON provider you need to add jersey-media-json-jackson
module to your pom.xml
file:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.25.1</version> </dependency>
Registering the Jackson module
Then register the JacksonFeature
in your Application
/ ResourceConfig
subclass:
@ApplicationPath("/api") public class MyApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(JacksonFeature.class); return classes; } }
@ApplicationPath("/api") public class MyApplication extends ResourceConfig { public MyApplication() { register(JacksonFeature.class); } }
If you don’t have an Application
/ ResourceConfig
subclass, you can register the JacksonFeature
in your web.xml
deployment descriptor. The specific resource, provider and feature fully-qualified class names can be provided in a comma-separated value of jersey.config.server.provider.classnames
initialization parameter.
<init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value> </init-param>
The MessageBodyWriter
provided by Jackson is JacksonJsonProvider
. For more details on how to use Jackson as a JSON provider, have a look at this answer. If you need to customize the ObjectMapper
, refer to this answer.
Fixing your resource class
By using the approach described above, you resource class can be as simple as:
@Path("/users") public class MyRestService { @GET @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8"}) public List<User> findUsers() { List<User> users = new ArrayList<>(); users.add(new User("Nick", "admin", "32", 47)); return Response.ok(users).build(); }
When requesting such endpoint, it will give you the expected JSON as result.