泽西,杰克逊和J&C的JSON格式化json.org/java解析器使用Curl命令

时间:2012-12-14 01:40:58

标签: java json curl jersey jackson

使用Java 6,Tomcat 7,Jersey 1.15,Jackson 2.0.6(来自FasterXml maven repo),& www.json.org解析器,我正在尝试 相当打印JSON字符串,因此它将通过curl -X GET命令行缩进。

我创建了一个简单的Web服务,它具有以下架构:

我的POJO(模型类):

Family.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Family {
    private String father;
    private String mother;

    private List<Children> children;

    // Getter & Setters
}

Children.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Children {
    private String name;
    private String age;
    private String gender;

    // Getters & Setters
}

使用Utility Class,我决定按如下方式对POJO进行硬编码:

public class FamilyUtil {

    public static Family getFamily() {
        Family family = new Family();
        family.setFather("Joe");
        family.setMother("Jennifer");

        Children child = new Children();
        child.setName("Jimmy");
        child.setAge("12");
        child.setGender("male");
        List<Children> children = new ArrayList<Children>();

        children.add(child);

        family.setChildren(children);
        return family;
    }
}

我的网络服务:

import java.io.IOException;

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

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jettison.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.myapp.controller.myappController;
import com.myapp.resource.output.HostingSegmentOutput;
import com.myapp.util.FamilyUtil;

@Path("")
public class MyWebService {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public static String getFamily() throws IOException, 
                                            JsonGenerationException, 
                                            JsonMappingException, 
                                            JSONException, 
                                            org.json.JSONException {
        ObjectMapper mapper = new ObjectMapper(); 
        String uglyJsonString = mapper.writeValueAsString(FamilyUtil.getFamily());
        System.out.println(uglyJsonString);
        JSONTokener tokener = new JSONTokener(uglyJsonString);
        JSONObject finalResult = new JSONObject(tokener);
        return finalResult.toString(4);         
    }
}

当我使用以下方式运行时:

curl -X GET http://localhost:8080/mywebservice

我在Eclipse的控制台中得到了这个:

{"father":"Joe","mother":"Jennifer","children":[{"name":"Jimmy","age":"12","gender":"male"}]}

但是从命令行的curl命令开始(这个响应更重要):

"{\n    \"mother\": \"Jennifer\",\n    \"children\": [{\n        \"age\": \"12\",\n        \"name\": \"Jimmy\",\n        \"gender\": \"male\"\n    }],\n    \"father\": \"Joe\"\n}"

这是添加换行符转义序列并放置双引号(但不应该像它一样缩进它应该在新行之后有4个空格但它全部在一行中)。

如果有人能指出我正确的方向,我将不胜感激。

2 个答案:

答案 0 :(得分:4)

我相信正在发生的事情是你当前配置的消息正文阅读器正在从你的方法返回你的String,并正确地转义它以使它是一个有效的JSON字符串(因为json不会让字符串常量中的换行符)。

这是你做的......我假设你正在使用杰克逊的消息体作者。 (例如JacksonJsonProvider)

您创建了一个@Provider,用于设置启用了Pretty Printing的ObjectMapper实例,如下所示:

@Provider
public class JacksonObjectMapperProvider implements ContextResolver<ObjectMapper> {

    /**
     * {@inheritDoc}
     */
    @Override
    public ObjectMapper getContext(final Class<?> type) {
        final ObjectMapper toReturn = new ObjectMapper();
        toReturn.enable(SerializationFeature.INDENT_OUTPUT); // This is the important setting
        toReturn.disable(MapperFeature.USE_ANNOTATIONS); // I have this one on but it's probably for other resources in the container testing it in, I don't know if you'd need it.
        return toReturn;
    }
}

然后让您的资源返回已解析的Family对象,而不是尝试将其转换为Json ...让Message Body Writer执行此操作...即

public class MyWebService {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Family getFamily() 
        return FamilyUtil.getFamily()
    }
}

和Voila:

$ curl http://<server>/<ctx-root>/<path>
{
  "father" : "Joe",
  "mother" : "Jennifer",
  "children" : [ {
    "name" : "Jimmy",
    "age" : "12",
    "gender" : "male"
  } ]
}

现在,我在使用JAX-RS应用程序配置注册了Provider和MessageBodyReader,但这可能会有很大的不同,具体取决于您是使用Jersey的servlet,使用自定义应用程序,使用Guice还是其他任何方式设置JAX-RS堆栈。

答案 1 :(得分:1)

只需使用GSON library

即可

这是泽西岛的一个例子 正常的Gson:

Gson gson = new Gson();
    String json = gson.toJson(obj);
    System.out.println(json);

JSON输出显示为紧凑模式,如下所示:

{"data1":100,"data2":"hello","list":["String 1","String 2","String 3"]}

要启用漂亮的打印,您应该使用GsonBuilder返回一个Gson对象:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String json = gson.toJson(obj);
    System.out.println(json);

输出将是这样的:

{
  "data1": 100,
  "data2": "hello",
  "list": [
    "String 1",
    "String 2",
    "String 3"
  ]
}

mkyong

的完整示例
package com.mkyong.core;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class GsonExample {
    public static void main(String[] args) {

    DataObject obj = new DataObject();
    // Gson gson = new Gson();

    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    String json = gson.toJson(obj);

    System.out.println(json);

    }
}