使用Curl Command使用Jersey,Jackson和json.org/java Parser进行JSON格式化

使用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个空格但它全部在一行中).

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

解决方法:

我相信你正在发生的事情是你当前配置的消息体阅读器正在从你的方法返回你的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堆栈.

上一篇:java – 如何访问HTTP Basic用户名?


下一篇:如何使用Jersey Rest Webservices和Java解析JSON数组