![](/img/trans.png)
[英]Jersey + Grizzly HTTP + Jackson (MessageBodyWriter not found for media type=application/xml)
[英]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.