Java 不带根节点的JAX-RS-JSON

Java 不带根节点的JAX-RS-JSON,java,json,jax-rs,Java,Json,Jax Rs,我有一个restful web服务,响应是: { "cities": [{ "id": "1", "name": "City 01", "state": "A1" }, { "id": "2", "name": "City 02", "state": "A1" }] } 但我想要这个: { [{ "id": "1", "name": "

我有一个restful web服务,响应是:

{
    "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上移植。

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

如果您也使用Glassfish,那么您可以通过将
org.codehaus.jackson.jaxrs
添加到war以及
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>
替换

... consumesCity(json) ...


好问题。我有一个类似的要求。我必须访问生成的原始响应并进行一些操作。我通过注册一个resonse过滤器,然后调整一个定制的ResonseWriter来实现这一点。有关更多详细信息,请参阅下面的链接

http://www.mentby.com/paul-sandoz/access-to-raw-xml-in-jersey.html
在响应过滤器中,您可以从生成的json中删除类名,或者更好的是,在响应中返回字符串,并使用自定义json序列化机制,如Google gson


让我知道这个解决方案是否有效。

上面Kim Burgaard的回答也适用于泽西之春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
org.springframework.web.context.ContextLoaderListener
org.springframework.web.context.request.RequestContextListener
Jersey Spring Web应用程序
com.sun.jersey.spi.spring.container.servlet.SpringServlet
com.sun.jersey.config.property.packages
org.codehaus.jackson.jaxrs
Jersey Spring Web应用程序
/服务/*
示例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>


您的模型(城市)类JAXB是如何注释的?这就是要控制XML和JSON之间的串行/反序列化。我的类如下:@XmlRootElement(name=“cities”)公共类cityTo实现可序列化{}谢谢你,Kim。但我仍在寻找一个可移植的解决方案。我得到的印象是,这种特定的行为是特定于供应商的,也就是说,集合返回类型的顶级JSON对象是数组,还是包含集合成员的字段的单个对象。看到Glassfish的引用实现返回后一种风格的集合,我有点沮丧。我认为返回JSON数组更直观。如果你找到更好的解决方案,请发布更新。我同意Kim的观点。虽然结构确实不同——主要是由于历史原因,特别是因为有些lib通过XML api处理JSON,这有时会强制使用包装器——但实际上没有更标准的方法,除非您希望使用自定义MessageBodyWriter/Reader实现。
<?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>
<?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>