Search code examples
javajsonjerseyjax-rsjersey-2.0

Serialize javax.ws.rs Entity to json


I want to serizalize to Json with org.glassfish.jersey implementation

Map<String, String> entity = Maps.newHashMap();
entity.put("foo", "bar");

Response response = Response.status(Response.Status.OK)
                            .entity(entity)
                            .type(MediaType.APPLICATION_JSON).build();

System.out.println(response.getEntity());

This map serialize to non standard { foo: "bar" }. I want to test this behaviour in unit test.


Solution

  • You can't test like this. What you are doing here

    Response response = Response.status(Response.Status.OK)
                                .entity(entity)
                                .type(MediaType.APPLICATION_JSON).build();
    

    is building an outbound response. In the JAX-RS framework, after we send out a response, e.g.

    @GET
    @Produced(MediaType.APPLICATION_JSON)
    public Response getResponse() {
        ...
        return Response.status(Response.Status.OK)
                        .entity(entity)
                        .type(MediaType.APPLICATION_JSON).build();
    }
    

    it still needs to through a MessageBodyWriter for the serialization to JSON.

    That being said, Jersey has a Test Framework, we can use to test our resource methods. You can find all the official examples at the Github

    A sample (with a few alterations):

    These are the minimum required Maven dependencies

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework</groupId>
            <artifactId>jersey-test-framework-core</artifactId>
            <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
            <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.13</version>
        </dependency>
    </dependencies>
    

    Test class

    public class TestJSONResource extends JerseyTest {
    
        @Override
        protected TestContainerFactory getTestContainerFactory() {
            return new GrizzlyTestContainerFactory();
        }
    
        @Path("test")
        public static class TestResource {
            @GET
            @Produces(MediaType.APPLICATION_JSON)
            public Response getJson() {
                Map<String, String> entity = Maps.newHashMap();
                entity.put("foo", "bar");
    
                Response response = Response.status(Response.Status.OK)
                        .entity(entity)
                        .type(MediaType.APPLICATION_JSON).build();
                return response;
            }
        }
    
        @Override
        protected DeploymentContext configureDeployment() {
            return DeploymentContext.builder(new ResourceConfig(TestResource.class))
                    .contextPath("context1/context2")
                    .build();
        }
    
        @Test
        public void testGet() {
            final WebTarget target = target("test");
            final String s = target.request().get(String.class);
            System.out.println(s);
        }
    }
    

    jersey-media-json-jackson provides the MessageBodyWriter and MessageBodyReader for processing JSON, which is implicitly registered for us.