8

私のアプリケーションでは、Jersey REST を使用して複雑なオブジェクトをシリアル化しています。これは非常にうまく機能します。しかし、単純に int または boolean を返すメソッドがいくつかあります。

Jersey は (私の知る限り) プリミティブ型を処理できません。おそらく、それらには注釈が付けられておらず、Jersey にはデフォルトの注釈がないためです。私は、RestBoolean や RestInteger のような複雑な型を作成することでこの問題を回避しました。これらは単純に int または boolean 値を保持し、適切な注釈を持ちます。

これらのコンテナ オブジェクトを記述するよりも簡単な方法はありませんか?

4

6 に答える 6

4

Gensonを見てください。同様の問題で私を大いに助けてくれました.Gensonでは、int、boolean、listsなどのジェネリックを使用できます...簡単な例を次に示します。

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getMagicList() {
    List<Object> objList = new ArrayList<>();
    stringList.add("Random String");
    stringList.add(121); //int
    stringList.add(1.22); //double
    stringList.add(false); //bolean

    return Response.status(Status.OK).entity(objList).build();
}

これにより、次のように非常に簡単に取得できる有効な JSON ウィッチが生成されます。

    Client client = Client.create();
    WebResource webResource = client.resource("...path to resource...");
    List objList = webResource.accept(MediaType.APPLICATION_JSON).get(ArrayList.class);
    for (Object obj : objList) {
        System.out.println(obj.getClass());
    }

Genson は、クライアント側でも JSON をデコードし、それぞれの正しいクラスを出力するのに役立つことがわかります。

于 2013-02-03T10:00:59.397 に答える
3

サービスまたはクライアントを作成していますか? サービス側では、単純にMessageBodyWriterを記述して、データのストリームを型の Java オブジェクトにシリアル化します。私のユース ケースでは、出力を JSON または XML に書き込んでいます。XML の場合は、クラスの先頭に 1 つの JAXB アノテーションを投げるだけで完了です。

これに関してJersey User guideを見ましたか?

3.6. 新しい表現のサポートの追加

于 2010-04-29T03:12:45.237 に答える
2

Jersey に適切な JSON ドキュメント (自然な json) を生成するように指示します。Rest アプリと JAXBContext リゾルバーに同じクラスを使用していますが、これが最もクリーンなカプセル化であることがわかりました。

より優れたプログラマーは、ヘルパーを実装して .class ファイルを反復処理し、@Annotation タグを識別することで適切なクラスを自動的にリストできます。独自のソースコードで実行する方法がわかりません。

これらの 2 つのリンクは、この余分な Java 専門用語の学習に役立ちました。すべてを箱から出してすぐに機能させるためのジャージーパラメーターがない理由がわかりません。

WEB-INF/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.myapp.rest.RESTApplication</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>RESTServlet</servlet-name>
  <url-pattern>/servlet/rest/*</url-pattern>
</servlet-mapping>

com.myapp.rest.RESTApplication.java

package com.myapp.rest;

import java.util.*;
import javax.ws.rs.core.Application;
import javax.ws.rs.ext.ContextResolver;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext;

public class RESTApplication extends Application implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    private Class<?>[] types;

    public RESTApplication() throws JAXBException {
        // list JAXB bean types to be used for REST serialization
        types = new Class[] {
            com.myapp.rest.MyBean1.class, 
            com.myapp.rest.MyBean2.class, 
        };
        context = new JSONJAXBContext(JSONConfiguration.natural().build(), types);
    }

    @Override
    public Set<Class<?>> getClasses() {
        // list JAXB resource/provider/resolver classes
        Set<Class<?>> classes = new HashSet<Class<?>>();
        //for(Class<?> type : types)
        //    classes.add(type);
        classes.add(MyBeansResource.class);
        classes.add(this.getClass()); // used as a ContextResolver class
        return classes;
    }

    @Override
    public JAXBContext getContext(Class<?> objectType) {
        // this is called each time when rest path was called by remote client
        for (Class<?> type : types) {
            if (type==objectType)
                return context;
        }
        return null;
    }
}

クラス MyBean1、MyBean2 はプレーンな Java オブジェクトであり、MyBeansResource クラスは @Path レスト関数を持つクラスです。あちこちに標準の jaxp @Annotations があることを期待して、特別なことは何もありません。この Java 専門用語の後、JSON ドキュメントは

  • ゼロまたは単一要素のリスト配列は、常に json 配列 ([] フィールド) として書き込まれます。
  • プリミティブ整数とブール フィールドは、json プリミティブとして記述されます (引用符なし)。

以下の環境を使用しています

  • サン Java JDK1.6.x
  • アパッチ トムキャット 6.x
  • Jersey v1.14 ライブラリ (jersey-archive-1.14.zip)
  • webapps/myapp/WEB-INF/lib フォルダーには、asm-3.3.1.jar、jackson-core-asl.jar、jersey-client.jar、jersey-core.jar、jersey-json.jar、jersey-server.jar があります。 、 jersey-servlet.jar ライブラリ
  • infomas-asl 検出ツールを使用する場合は、オプションの annotation-detector.jar を追加します

jersey-archive.zip には古い asm-3.1.jar ファイルがあり、おそらく正常に動作しますが、 chapter_deps.html は新しいファイルにリンクしています。上部のリンクリストを参照してください。

編集 優れた (高速で軽量、わずか 15KB) 注釈発見ツールを見つけました。実行時に型を自動検出し、新しい Java(jaxb) Bean が追加されるたびに RESTApplication を編集する必要がなくなった方法については、この投稿を参照してください。

https://github.com/rmuller/infomas-asl/issues/7

于 2012-09-27T14:49:59.753 に答える
2

実際には、JSON の自然な構築を使用する次のようなカスタム ContextResolver Provider を作成することをお勧めします。

   @Provider
   public class YourContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext context;
    private Class<?>[] types = { YourSpecialBean.class };

    public YourContextResolver() throws Exception {
        this.context = new JSONJAXBContext(
                JSONConfiguration.natural().build(), types);
    }

    public JAXBContext getContext(Class<?> objectType) {
        for (int i = 0; i < this.types.length; i++)
            if (this.types[i].equals(objectType)) return context;

        return null;
    }
}

ここで注目すべき唯一の特別な点は、Class[] 内の YourSpecialBean.class です。これは、このプロバイダが自然に解決するクラス タイプの配列を定義します。

于 2010-05-20T21:21:27.810 に答える
2

Jersey でプリミティブ型を返すことに問題があることを発見しました。代わりに String を返すことにしました。これはきれいではないかもしれませんが、あまり汚れていないと思います。ほとんどの場合、サーバーと同じ作成者によって作成された Java クライアントは、そのような文字列の戻り値をラップして、int に戻すことができます。他の言語で記述されたクライアントは、何らかの方法で戻り値の型を認識している必要があります。

RestInteger を定義すると、RestBoolean も別のオプションになる可能性がありますが、それはより面倒であり、魅力的であるとは思えません。

それとも、ここで重要な何かが欠けているのでしょうか?

于 2013-10-07T17:09:32.490 に答える