Why JSON pretty print is not working?

1.5k views Asked by At

I am trying to do the same thing as this question, but I've tried every possibility I found and I could not make it work.

So far, I have this code:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
//import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.annotations.providers.jaxb.json.BadgerFish;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.annotation.JacksonFeatures;

@Path(value = "/mock")
@Controller
public class MockController {

    @BadgerFish
    @GET
    @Path(value = "/get")
    @Produces(MediaType.APPLICATION_JSON_VALUE)
    @JacksonFeatures(serializationEnable = {SerializationFeature.INDENT_OUTPUT})
    public Container getMockedContainer() {
        return newContainer();
    }

    @BadgerFish
    @GET
    @Path(value = "/getXML")
    @Produces(value = MediaType.APPLICATION_XML_VALUE)
    public Container getMockedContainerXML() {
        return newContainer();
    }

    //MORE CODE HERE
}

I can go to http://localhost:8081/containerMocked/mock/getXML/ and get the expected XML output, easy. But when I try localhost/.../get/ I get the correct data but not pretty printed.

At least to me, @Produces(MediaType.APPLICATION_JSON) and @JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT}) should be enough.

What am I doing wrong?

DISCLAIMER: I will not put here what newContainer() does as it involves too many classes. The thing you must understand is that this Main

public static void main(String[] args) throws javax.xml.bind.JAXBException {
    Container container = new MockController().newContainer();
    final javax.xml.bind.JAXBContext jaxbContext = javax.xml.bind.JAXBContext.newInstance(Container.class);
    javax.xml.bind.Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(container, System.out);
}

Will output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container>
    <leaf>
        <id>int32</id>
        <possibleValues/>
        <type>int32</type>
        <value>2147483647</value>
    </leaf>
    <id>device</id>
</container>

and http://localhost:8081/containerMocked/mock/get/ will output:

{"container":{"leaf":{"id":{"$":"int32"},"possibleValues":{},"type":{"$":"int32"},"value":{"$":"2147483647"}},"id":{"$":"device"}}}

EDIT: I have just tested @Formatted annotation according to this link and I also got no results.

Why these annotations are not working, but @Produces and @BadgerFish work normally for example?

I would prefer to do it in the most simple way if possible. And for me, the most simple way is make one of the above annotations work as expected.

1

There are 1 answers

2
Sam Berry On

You could try registering an ObjectMapper provider with your JAX-RS implementation:

@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {

    @Override
    public ObjectMapper getContext(Class<?> aClass) {
        return new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
    }
}