4

Jersey を使用した JAX-RS REST サービスがあります。JSONマーシャリングにJAXBを使用します(つまり、@XmlRootElement)メソッドの1つは、JPAで永続化されたオブジェクトのリストを返します。

このリストにエントリが含まれている場合、期待どおりに機能します。例:

{"androidDevice":[{"email":"dagfinn.parnas@d2.no","timeCreated":"2012-10-19T
22:41:26.862+02:00"},{"email":"dagfinn.parnas@d1.com","timeCreated":"2012-10-
19T22:41:38.093+02:00"}]}

ただし、リストが空 (または null) の場合は、{} が返されることを期待します。

代わりに null を返します。例:

$ curl  -i -H "Accept: application/json" http://....
HTTP/1.1 200 OK
Content-Type: application/json

null

ここにコードがあります

    @GET
@Produces( { MediaType.APPLICATION_JSON ,  MediaType.APPLICATION_XML})
public List<AndroidDevice> getAndroidDevices() {
    logger.info("getAndroidDevices method called");


    EntityManager entityManager = entityMangerFactory.createEntityManager();  
    List<AndroidDevice> resultList = entityManager.createNamedQuery(AndroidDevice.QUERY_ALL_ENTRIES,  
            AndroidDevice.class).getResultList();  

    //avoid returning content null. (doesn't work)
    if(resultList==null){
        resultList=new ArrayList<AndroidDevice>();
    }

    return resultList;
}

Jersey が空の JSON リストを返すようにする方法はありますか (ResponseBuilder をハードコーディングする以外に) ?

代わりに、そのようなイベントに対して別の応答コードを提供する必要がありますか?

更新: このバグ レポートに関するヒントを Twitter で入手しました。このバグ レポートは、修正されないという結論に達しました

Update2: 以下のソリューションに加えて、構成用のアプリケーション (web.xml で参照) を使用していたため、そこに Provider クラスを手動で追加する必要がありました。関連するコードは次のとおりです。

public class JAXRSApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> set = new HashSet<Class<?>>();
        //Add all endpoints to this set
        set.add(AndroidDeviceEndpoint.class);
        //Add Providers
        set.add(JAXBContextResolver.class);
        return set;
    }   
}
4

3 に答える 3

4

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

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
    private final JAXBContext context;
    private final Set<Class> types;
    private Class[] ctypes = { AndroidDevice.class}; //your pojo class
    public JAXBContextResolver() throws Exception {
        this.types = new HashSet(Arrays.asList(ctypes));
        this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
                ctypes); //json configuration
    }

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

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

于 2012-10-20T01:32:58.657 に答える
2

I encountered the same issue. In Jersey 1.09 an empty array is sent as null while a filled array is written correctly. Now I use Jersey 1.19.4 and in this version an empty array is written correctly as {}.

于 2018-06-05T07:39:08.470 に答える
2

安らかなサービスがnullを返す場合、私は同じ問題を抱えています。私がしたことは、リストのサイズを確認することだけです。リストのサイズが 0 の場合、次を使用します。

return Response.ok("{}", req.getContentType()).status(Response.Status.OK); 

本体で「{}」を返します。私のrestkitクライアントは今、それに満足しています.

于 2013-01-16T00:39:22.920 に答える