6

サーバー コンポーネント用の Web サービスを作成するために Jersey を使用しています。残念ながら、データは常に文字列としてフォーマットされるため、JSON 応答のフォーマットに問題があります。

さまざまなフィールドタイプを持つ単純な JAXB アノテーション付き POJO があります。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbPojo {

    @XmlElement(name = "id_64")
    private Long id;

    @XmlElement(name = "desc")
    private String description;

    private Boolean active;

    // getters and setters
    ..
}

単純なリソースで、受信オブジェクトを返します。

@Path("/jaxb_pojo")
public class JaxbPojoResource {

    @POST
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON })
    public JaxbPojo processBidRequest(JaxbPojo pojo) {
         return pojo;
    }

}

次の JSON データを使用してリソースにリクエストを送信すると、オブジェクトはリソース メソッド内で正しく入力されます。ただし、返される JSON データのフィールド タイプは常に文字列としてフォーマットされます。

me@host:/tmp $ cat simple_jaxb_pojo 
{"id_64":99,"desc":"simple JAXB POJO","active":true}

me@host:/tmp $ curl -X POST -H "Content-Type: application/json" --data-binary @simple_jaxb_pojo http://localhost/srvr/rest/jaxb_pojo
{"id_64":"99","desc":"simple JAXB POJO","active":"true"}

使用されるすべての jar ファイル (jsr311-api-1.1.1.jar、jersey-core-1.6.jar、jersey-json-1.6.jar、jersey-server-1.6.jar) は、tomcat/lib パスに直接含まれています。JAX-RS ライブラリは、Maven pom.xml を介してスコープ "provided" で使用されます。

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>jsr311-api</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
</dependency>

私の web.xml は次のようになります。

<servlet>
    <servlet-name>RestServlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.rest.RestResourcesApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

..

<servlet-mapping>
    <servlet-name>RestServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

POJO のタイプを使用するように、Jackson を明示的に構成する必要があるのでしょうか。私はこのテーマにかなり慣れていないので、これに関するすべての情報を投稿しました。誰かが助けてくれることを願っています。

4

2 に答える 2

1

user463324のソリューションは優れています。通常、このソリューションを使用して、JavaオブジェクトをJSONに変換したり元に戻したりできます。これは、ジャクソンライブラリに基づいています。

JAXBに基づいてJSONを取得する場合は、いくつかの構成オプションが提供されているため、シリアル化と逆シリアル化の方法を制御できます。デフォルトの構成では、質問で指摘されているように、文字列形式が使用されます。

より重要なJSON形式の変更を実現するには、JerseyJSONプロセッサー自体を構成する必要があります。JSONConfigurationインスタンスには、さまざまな構成オプションを設定できます。次に、インスタンスをさらに使用して、この領域の主要な構成ポイントとして機能するJSONConfiguratedJSONJAXBContextを作成できます。特殊なJSONJAXBContextをJerseyに渡すには、最終的にJAXBContextContextResolverを実装する必要があります。

    @Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {

    private final JAXBContext context;
    private final Set<Class> types;
    private Class[] ctypes = { JaxbPojo.class};
    public JAXBContextResolver() throws Exception {
        this.types = new HashSet(Arrays.asList(ctypes));
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
                ctypes);
    }

    @Override
    public JAXBContext getContext(Class<?> objectType) {
        return (types.contains(objectType)) ? context : null;
    }
}

詳細については、ジャージの公式ドキュメントを参照してください。

于 2012-10-19T03:08:07.883 に答える
1

興味深い問題です。なぜこれが起こっているのか正確にはわかりませんが、追加してみてください:

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

web.xml の Jersey サーブレット定義に追加します。Jersey では JSON を生成するためにこれが必要だと思っていましたが、この init-param を削除すると、同じ問題が発生しました。

于 2012-10-18T15:55:18.870 に答える