我正在为Jersey的RESTtFull web应用程序编写一个Blog响应列表。如何用泽西制作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
答案 0 :(得分:0)
Jersey没有提及它可以处理HashMap
到XML表示的转换。
XML媒体类型(text / xml,application / xml和application /...+ xml)
- javax.xml.transform.Source
- javax.xml.bind.JAXBElement
- 应用程序提供的JAXB类(使用@XmlRootElement或@XmlType注释的类型)
即使您在散列映射中使用的其他对象被注释为转换为XML,它也不起作用。
我建议您创建一个专用的表示对象,例如BlogListResponse
,其中注明了@XmlXXX
注释,对于您尝试使用的Blog
实体也是如此。< / p>
答案 1 :(得分:0)
提到by @Frederik Heremans时,问题出在(Hash)Map
上。但即使你让地图工作,你仍然没有一个有效的RSS格式。你只需要随机的XML,RSS阅读器无法阅读。
如果您想要真正的RSS格式,请查看RSS Wikipedia page。在那里,您将看到不同的RSS版本和格式。之后,您应该找到一个专门处理RSS源的库。我个人建议Rome。我认为它是最受欢迎的Java库。 (请务必查看链接。有很多例子。)
罗马图书馆有一个单一的根界面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);
}
}
}
您需要在Jersey应用程序中注册此提供程序,可以通过程序包扫描进行隐式注册,也可以使用ResourceConfig
进行显式注册。
此提供程序处理SyndFeed
的序列化和反序列化。因此,在您的资源中,您可以创建SyndFeed
个实例,并将其作为响应实体返回。提供程序将处理序列化。示例提供程序还将从序列化形式的反序列化处理回到SyndFeed
类,以防您想在客户端上使用它,可能用于测试。
您可以在this Gist
中找到完整的工作测试用例