JAX-RS - JSON without root node

后端 未结 3 1862
太阳男子
太阳男子 2021-01-12 09:08

I have a restful web service, and the response is:

{
    \"cities\": [{
        \"id\": \"1\",
        \"name\": \"City 01\",
        \"state\": \"A1\"
    }         


        
相关标签:
3条回答
  • 2021-01-12 09:28

    Good question. I have had an requirement similar to this. I had to have access to the generated raw response and do some manipulation. I achieved that by registering a resonse filter and then adapt a custom reponsewriter. See link below for more details.

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

    In your response filter, you could clip out the class name from generated json, or better yet, return String in response and use custom json serialization mechanism like Google-gson.

    Let me know if this solution works.

    0 讨论(0)
  • 2021-01-12 09:52

    Answer from Kim Burgaard above works also for Jersey Spring WS. I had the same problem using Glassfish 3.0 and solved it adding the parameter shown below.

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

    Example 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>
    
    0 讨论(0)
  • 2021-01-12 09:53

    I had the same problem with Glassfish v3. I found this behavior depends on the JAX-RS implementation and switching to Codehaus' Jackson JAX-RS implementation solved the problem for me.

    If you're using Glassfish as well, then you can solve the problem by adding org.codehaus.jackson.jaxrs to your war as well as to the WEB-INF/web.xml configuration as follows:

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

    Alternatively, you might be able to simply intercept the response in the client:

    function consumesCity(json) {
       ...
    }
    

    Replace

    ... consumesCity(json) ...
    

    with

    function preprocess(json) {
        return json.city;
    }
    
    ... consumesCity(preprocess(json)) ...
    
    0 讨论(0)
提交回复
热议问题