2017-02-08 8 views
0

JerseyでRESTtFull WebアプリケーションのBlogレスポンスのリストを作成しています。ジャージーでRSSフィードを作成するにはどうすればいいですか?ジャージーレスポンスRSSフィード(メディアタイプ= application/rss + xmlのMessageBodyWriterが見つかりません)

public List<Blog> list() throws Exception { 

     List<Blog> blogs= new ArrayList<Blog>(); 
     Query query = new Query(); 

     blogs= SpringDataDBUtils.getMongoOperations().find(query, Blog.class); 

     return blogs; 
    } 

しかし、それは動作しません:私はこれが私のサービス層でのブログのリスト方式である

@GET 
@Produces("application/rss+xml") 
public Response list() { 
    Map<Object, Object> apiResponse  = new HashMap<Object, Object>(); 
    Map<Object, Object> serviceResponse = new HashMap<Object, Object>(); 

    try { 
     List<Blog> blogs = blogService.list(); 
     serviceResponse.put("total", blogs.size()); 
     serviceResponse.put("list", blogs); 
     apiResponse.put("apiresponse", serviceResponse); 

     return Response.ok(apiResponse).build(); 

    } catch (Exception e) { 
     logger.error("Error in getting blog list:", e); 
     apiResponse.put("error", e.getMessage()); 
    } 

    return Response.status(500).entity(apiResponse).build(); 
} 

で試してみました。これは、エラーが発生します。

MessageBodyWriter not found for media type=application/rss+xml, type=class java.util.HashMap 

答えて

0

ジャージーは、それがXML表現にHashMapの変換を処理することができます言及していません。

XML media types (text/xml, application/xml and application/...+xml)

  • javax.xml.transform.Source
  • javax.xml.bind.JAXBElement
  • Application supplied JAXB classes (types annotated with @XmlRootElement or @XmlType)

ハッシュマップで使用する他のオブジェクトに注釈を付けてXMLに変換しても、動作しません。私はあなたが専用の表現オブジェクトを作成示唆

は、たとえば@XmlXXX注釈で注釈されているBlogListResponse、のために、同じことがあなたが使用しようとしているBlogエンティティのために行きます。

0

by @Frederik Heremansのように、問題は(Hash)Mapです。しかし、マップを稼働させても、有効なRSSフォーマットをまだ持っていないことさえあります。あなたはランダムなXMLを持っているだけで、RSSリーダーが読むことは不可能です。

実際のRSSフォーマットをご希望の場合は、RSS Wikipedia pageをご覧ください。そこには、さまざまなRSSのバージョンとフォーマットが表示されます。その後、RSSフィードを正しく処理するための専用ライブラリが必要です。個人的に私はRomeを提案します。私はそれがそこで最も人気のあるJavaライブラリだと思います。 (リンクをチェックアウトしてください。多くの例があります)。

ローマライブラリーには、RSSフィードをモデル化する単一のルートインターフェースSyndFeed(複数のRSSバージョンをサポートしています)があります。 SyndFeedを使用すると、(de)シリアライズを処理するJAX-RS Providerを作成できます。ここでは完全な作業例

あなたは暗黙的、または明示的に ResourceConfigとのパッケージスキャンを通じて、あなたのジャージーのアプリケーションでこのプロバイダを登録する必要があります
import com.rometools.rome.feed.synd.SyndFeed; 
import com.rometools.rome.io.FeedException; 
import com.rometools.rome.io.SyndFeedInput; 
import com.rometools.rome.io.SyndFeedOutput; 

import javax.ws.rs.Consumes; 
import javax.ws.rs.InternalServerErrorException; 
import javax.ws.rs.Produces; 
import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.ext.MessageBodyReader; 
import javax.ws.rs.ext.MessageBodyWriter; 
import javax.ws.rs.ext.Provider; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 

/** 
* Example JAX-RS provider for Rome {@code SyndFeed}. 
*/ 
@Provider 
@Produces("application/rss+xml") 
@Consumes("application/rss+xml") 
public class SyndFeedProvider implements MessageBodyWriter<SyndFeed>, MessageBodyReader<SyndFeed> { 

    @Override 
    public boolean isWriteable(Class<?> type, Type genericType, 
           Annotation[] annotations,MediaType mediaType) { 
     return SyndFeed.class.isAssignableFrom(type); 
    } 

    @Override 
    public long getSize(SyndFeed syndFeed, Class<?> type, Type genericType, 
         Annotation[] annotations, MediaType mediaType) { 
     return -1; 
    } 

    @Override 
    public void writeTo(SyndFeed syndFeed, Class<?> type, Type genericType, 
         Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, 
         Object> httpHeaders, OutputStream entityStream) 
      throws IOException, WebApplicationException { 

     SyndFeedOutput output = new SyndFeedOutput(); 
     OutputStreamWriter writer = new OutputStreamWriter(entityStream); 
     try { 
      output.output(syndFeed, writer); 
     } catch (FeedException e) { 
      throw new InternalServerErrorException(e); 
     } 
    } 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, 
           Annotation[] annotations, MediaType mediaType) { 
     return SyndFeed.class.isAssignableFrom(type); 
    } 

    @Override 
    public SyndFeed readFrom(Class<SyndFeed> type, Type genericType, 
          Annotation[] annotations, MediaType mediaType, 
          MultivaluedMap<String, String> httpHeaders, 
          InputStream entityStream) throws IOException, WebApplicationException { 

     InputStreamReader reader = new InputStreamReader(entityStream); 
     SyndFeedInput input = new SyndFeedInput(); 

     try { 
      return input.build(reader); 
     } catch (FeedException e) { 
      throw new InternalServerErrorException(e); 
     } 
    } 
} 

です。

このプロバイダーは、SyndFeedのシリアライズとデシリアライズの両方を処理します。したがって、あなたのリソースでは、SyndFeedインスタンスを作成し、それを応答エンティティとして返すことができます。プロバイダはシリアル化を処理します。また、サンプルプロバイダは、シリアライズされたフォームの逆シリアル化をSyndFeedクラスに戻して処理します。

完全に動作するテストケースは、this Gist

です。
関連する問題