为什么 JSON 美化输出不起作用?

3

我正在尝试做与这个问题相同的事情,但我尝试过所有可能性,仍然无法使它工作。

目前为止,我有以下代码:

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
}

我可以访问 http://localhost:8081/containerMocked/mock/getXML/ 并获得预期的 XML 输出,非常容易。但是当我尝试 localhost/.../get/ 时,我得到了正确的数据但没有漂亮的格式。
至少对我来说,@Produces(MediaType.APPLICATION_JSON)@JacksonFeatures(serializationEnable = { SerializationFeature.INDENT_OUTPUT}) 应该足够了。
我做错了什么?
免责声明:由于牵涉到太多类,我不会在此处放置 newContainer() 的内容。您必须理解的是,这个 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);
}

输出结果为:

<?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>

访问 http://localhost:8081/containerMocked/mock/get/ 将会输出:

{"container":{"leaf":{"id":{"$":"int32"},"possibleValues":{},"type":{"$":"int32"},"value":{"$":"2147483647"}},"id":{"$":"device"}}}
编辑:我刚刚根据这个链接测试了@Formatted注释,但我也没有得到任何结果。

为什么这些注释不起作用,但是@Produces@BadgerFish却正常工作呢?

如果可能的话,我更愿意以最简单的方式完成它。对我而言,最简单的方法就是让上述注释之一按预期工作。


请注意,您可以在路径中省略get。HTTP动词将传达该信息。 - Sam Berry
这只是因为我已经在项目中使用了该注释,所以它才存在。我会尝试不使用它。 - Patrick Bard
1个回答

1
你可以尝试在JAX-RS实现中注册ObjectMapper提供程序:
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {

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

我尝试着实现了类似于我提到的问题答案的东西,基于你所说的。但是我不确定如何正确地实现它。我看过一些ObjectMapper的例子,但我从未使用过它,我该如何将我的数据传递给它呢? - Patrick Bard
@PatrickBard 看起来你在使用RESTEasy?如果是这样,当容器(或任何Java对象)被转换为响应体时,RE将在幕后为你处理。 - Sam Berry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接