簡體   English   中英

澤西島產生響應RSS提要(找不到媒體類型= application / rss + xml的MessageBodyWriter)

[英]Jersey Produce response RSS Feed (MessageBodyWriter not found for media type=application/rss+xml)

我正在使用Jersey為我的RESTtFull Web應用程序編寫Blog響應列表。 如何使用Jersey生產RSS feed? 我嘗試過

@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();
}

這是我的服務層中的博客列表方法:

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;
    }

但這行不通。 它產生錯誤:

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

Jersey並未提及它可以處理HashMap到XML表示的轉換。

XML媒體類型(文本/ xml,應用程序/ xml和應用程序/...+xml)

  • javax.xml.transform.Source
  • javax.xml.bind.JAXBElement
  • 應用程序提供的JAXB類(用@XmlRootElement或@XmlType注釋的類型)

即使您對哈希圖中使用的其他對象進行了注釋以轉換為XML,也無法使用。

我建議您創建一個專用的表示對象,例如BlogListResponse ,該對象帶有@XmlXXX批注,您嘗試使用的Blog實體也是如此。

正如@Frederik Heremans提到的那樣 ,問題出在(Hash)Map 但是,即使您可以使用地圖,您甚至都不會擁有有效的RSS格式。 您將只有隨機XML,RSS閱讀器無法讀取。

如果您想使用真正的RSS格式,則應查看RSS Wikipedia頁面 在這里,您將看到不同的RSS版本和格式。 之后,您應該找到一個可以正確處理RSS提要的專用庫。 我個人會建議羅馬 我認為它是那里最受歡迎的Java庫。 (確保檢查出鏈接。有很多示例)。

Rome庫只有一個根接口SyndFeed ,可對RSS feed進行建模(它支持多個RSS版本)。 使用該SyndFeed您可以創建一個處理(反序列化)的JAX-RS Provider 這是一個完整的工作示例

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);
        }
    }
}

您將需要通過包掃描隱式地或通過ResourceConfig顯式地在Jersey應用程序中注冊此提供程序。

該提供程序可處理SyndFeed序列化和反序列化。 因此,您可以在資源中創建SyndFeed實例,然后將其作為響應實體返回。 提供者將處理序列化。 如果您想在客戶端上使用它(例如進行測試),示例提供程序還將處理程序從其序列化形式反序列化回SyndFeed類。

您可以在此要點中找到完整的工作測試用例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM