JAX-RS - 没有根节点的JSON

时间:2011-01-29 17:11:20

标签: java json jax-rs

我有一个安静的网络服务,响应是:

{
    "cities": [{
        "id": "1",
        "name": "City 01",
        "state": "A1"
    }, {
        "id": "2",
        "name": "City 02",
        "state": "A1"
    }]
}

但我想要这个:

{
    [{
        "id": "1",
        "name": "City 01",
        "state": "A1"
    }, {
        "id": "2",
        "name": "City 02",
        "state": "A1"
    }]
}

如何配置JAX-RS以仅使用JAX-RS功能而不使用实现特定功能来生成没有根节点的JSON?我的代码需要可以在任何appserver上移植。

3 个答案:

答案 0 :(得分:4)

我遇到了与Glassfish v3相同的问题。我发现这种行为取决于JAX-RS的实现,切换到Codehaus的Jackson JAX-RS实现为我解决了这个问题。

如果您正在使用Glassfish,那么您可以通过在战争中添加org.codehaus.jackson.jaxrs以及WEB-INF/web.xml配置来解决问题,如下所示:

<!-- REST -->

<servlet>
  <servlet-name>RESTful Services</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
    <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
  </init-param>
  <init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>you.service.packages;org.codehaus.jackson.jaxrs</param-value>
    <!-- NOTE: The last element above, org.codehaus.jackson.jaxrs, replaces the default
       JAX-RS processor with the Codehaus Jackson JAX-RS implementation. The default
       JAX-RS processor returns top-level arrays encapsulated as child elements of a
       single JSON object, whereas the Jackson JAX-RS implementation return an array.
    -->
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>RESTful Services</servlet-name>
  <url-pattern>/your/rest/path/*</url-pattern>
</servlet-mapping>

或者,您可以简单地拦截客户端中的响应:

function consumesCity(json) {
   ...
}

替换

... consumesCity(json) ...

function preprocess(json) {
    return json.city;
}

... consumesCity(preprocess(json)) ...

答案 1 :(得分:1)

好问题。我有类似的要求。我必须能够访问生成的原始响应并进行一些操作。我通过注册谐振滤波器然后调整自定义响应编写器来实现这一点。请参阅以下链接了解更多详情。

http://www.mentby.com/paul-sandoz/access-to-raw-xml-in-jersey.html

在你的响应过滤器中,你可以从生成的json中剪切出类名,或者更好的是,在响应中返回String并使用像Google-gson这样的自定义json序列化机制。

如果此解决方案有效,请告诉我。

答案 2 :(得分:0)

来自Kim Burgaard的回答以上也适用于Jersey Spring WS。我使用Glassfish 3.0遇到了同样的问题并解决了它添加如下所示的参数。

示例web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>org.codehaus.jackson.jaxrs</param-value>
<!--             NOTE: The last element above, org.codehaus.jackson.jaxrs, replaces the default
               JAX-RS processor with the Codehaus Jackson JAX-RS implementation. The default
               JAX-RS processor returns top-level arrays encapsulated as child elements of a
               single JSON object, whereas the Jackson JAX-RS implementation return an array.-->
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

示例applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <!--  Scan for both Jersey Rest Annotations and persistence classes  -->
    <context:component-scan base-package="your.service.packages"/>
</beans>