Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jersey生成响应RSS源(未找到媒体类型=应用程序/RSS+;xml的MessageBodyWriter)_Java_Spring Boot_Jersey - Fatal编程技术网

Java Jersey生成响应RSS源(未找到媒体类型=应用程序/RSS+;xml的MessageBodyWriter)

Java Jersey生成响应RSS源(未找到媒体类型=应用程序/RSS+;xml的MessageBodyWriter),java,spring-boot,jersey,Java,Spring Boot,Jersey,我正在用Jersey为我的RESTtFull Web应用程序写一个博客回复列表。如何使用jersey制作RSS提要?我试过了 @GET @Produces("application/rss+xml") public Response list() { Map<Object, Object> apiResponse = new HashMap<Object, Object>(); Map<Object, Object> serviceRe

我正在用Jersey为我的RESTtFull Web应用程序写一个博客回复列表。如何使用jersey制作RSS提要?我试过了

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

Jersey没有提到它可以处理
HashMap
到XML表示的转换

XML媒体类型(text/XML、application/XML和application/..+XML)

  • javax.xml.transform.Source
  • javax.xml.bind.JAXBElement
  • 应用程序提供的JAXB类(用@XmlRootElement或@XmlType注释的类型)
即使在hashmap中使用的其他对象被注释为转换为XML,它也不会工作

我建议您创建一个专用的表示对象,例如用
@XmlXXX
注释的
BlogListResponse
,您尝试使用的
Blog
实体也是如此。

如前所述,问题在于
(哈希)映射
。但是,即使你让地图工作,你仍然没有一个有效的RSS格式。您将得到随机的XML,这对于RSS阅读器来说是不可能读取的

如果您想要真正的RSS格式,您应该查看。在这里,您将看到不同的RSS版本和格式。之后,您应该找到一个能够正确处理RSS提要的专用库。我个人建议。我认为它是最流行的Java库。(一定要查看链接。这里有很多例子)

罗马图书馆有一个单一的根接口
SyndFeed
,它为RSS提要建模(它支持多个RSS版本)。使用该
SyndFeed
可以创建一个处理(反)序列化的。下面是一个完整的工作示例

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);
        }
    }
}
导入com.rometools.rome.feed.synd.SyndFeed;
导入com.rometools.rome.io.FeedException;
导入com.rometools.rome.io.SyndFeedInput;
导入com.rometools.rome.io.SyndFeedOutput;
导入javax.ws.rs.Consumes;
导入javax.ws.rs.InternalServerErrorException;
导入javax.ws.rs.products;
导入javax.ws.rs.WebApplicationException;
导入javax.ws.rs.core.MediaType;
导入javax.ws.rs.core.MultivaluedMap;
导入javax.ws.rs.ext.MessageBodyReader;
导入javax.ws.rs.ext.MessageBodyWriter;
导入javax.ws.rs.ext.Provider;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.lang.annotation.annotation;
导入java.lang.reflect.Type;
/**
*罗马{@code-SyndFeed}的JAX-RS提供程序示例。
*/
@提供者
@生成(“应用程序/rss+xml”)
@使用(“应用程序/rss+xml”)
公共类SyndFeedProvider实现MessageBodyWriter、MessageBodyReader{
@凌驾
公共布尔值可写(类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
返回SyndFeed.class.isAssignableFrom(类型);
}
@凌驾
公共长getSize(SyndFeed SyndFeed,类类型,类型genericType,
注释[]注释,MediaType(MediaType){
返回-1;
}
@凌驾
public void writeTo(SyndFeed SyndFeed,类类型,类型genericType,
注释[]注释、MediaType MediaType、多值Map httpHeaders、OutputStream entityStream)
抛出IOException、WebApplicationException{
SyndFeedOutput=新的SyndFeedOutput();
OutputStreamWriter writer=新的OutputStreamWriter(entityStream);
试一试{
输出(syndFeed,writer);
}捕获(FEEDE){
抛出新的InternalServerErrorException(e);
}
}
@凌驾
公共布尔值可读取(类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
返回SyndFeed.class.isAssignableFrom(类型);
}
@凌驾
公共SyndFeed readFrom(类类型、类型genericType、,
注释[]注释,MediaType MediaType,
多值MAP HttpHeader,
InputStream entityStream)引发IOException、WebApplicationException{
InputStreamReader reader=新的InputStreamReader(entityStream);
SyndFeedInput=新的SyndFeedInput();
试一试{
返回input.build(reader);
}捕获(FEEDE){
抛出新的InternalServerErrorException(e);
}
}
}
您需要在Jersey应用程序中注册此提供程序,可以通过包扫描隐式注册,也可以通过
ResourceConfig
显式注册

此提供程序处理序列化和反序列化
SyndFeed
。因此,在您的资源中,您可以创建
SyndFeed
实例,并将其作为响应实体返回。提供程序将处理序列化。示例提供程序还将反序列化从其序列化形式处理回
SyndFeed
类,以防您想在客户端上使用它,可能是为了测试

您可以在中找到完整的工作测试用例

MessageBodyWriter not found for media type=application/rss+xml, type=class java.util.HashMap
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);
        }
    }
}