栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在RESTful Web服务中使用多个资源

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在RESTful Web服务中使用多个资源

一种解决方案是只读取

InputStream
。您可以将包裹在
InputStream
ZipInputStream
。有了,
ZipInputStream
您可以得到
ZipEntry
with
ZipInputStream.getNextEntry()
,然后可以得到与文件名
ZipEntry.getName()
。然后只要检查名称即可
endsWith(".xml")

不过,您需要消耗

application/octet-stream
。这是一个简单的例子

@Path("/zip")public class ZipResource {    @POST    @Consumes(MediaType.APPLICATION_OCTET_STREAM)    public Response postZipFile(InputStream is) throws Exception {        StringBuilder builder;        try (ZipInputStream zip = new ZipInputStream(is)) { builder = new StringBuilder("==== Data ====n"); ZipEntry entry; while ((entry = zip.getNextEntry()) != null) {     String filename = entry.getName();     if (filename.endsWith(".xml")) {         builder.append("name: ").append(entry.getName()).append("n");         String xml = filePartToString(zip, (int) entry.getSize());         builder.append("data: ").append(xml).append("n");     }     zip.closeEntry(); }        }        return Response.ok(builder.toString()).build();    }    private String filePartToString(InputStream is, int size) throws Exception {        String xml;        byte[] buff = new byte[size];        is.read(buff, 0, size);        return new String(buff);    }}

这是一个测试

@Testpublic void testResteasy() throws Exception {    WebTarget target = client.target( TestPortProvider.generateURL(base_URI)).path("zip");    File file = new File("C:/test/test.zip");    Response response = target.request().post( Entity.entity(file, MediaType.APPLICATION_OCTET_STREAM));    System.out.println(response.getStatus());    System.out.println(response.readEntity(String.class));    response.close();}

在zip中使用这些文件

test1.xml---------<test1>hello world</test1>test2.xml---------<test2>hello squirrel</test2>test3.json----------{    "test3":"Hello Girls"}

我得到以下结果

==== Data ====name: test1.xmldata: <test1>hello world</test1>name: test2.xmldata: <test2>hello squirrel</test2>

顺便说一句,如果您可以控制数据的发送方式,则可能还需要研究多部分解决方案。您可以在其中设置内容类型,并可以命名每个部分,以方便访问它们。

您可以在此处看到Resteasy对multipart的支持以及所需的依赖项。


更新

如果 必须
使用

application/zip
,则对此没有标准支持。所以你需要自己动手
MessageBodyReader
。它可以像包装并返回已经提供的那样简单
InputStream

@Provider@Consumes("application/zip")public class ZipMessageBodyReader implements MessageBodyReader<ZipInputStream> {    @Override    public boolean isReadable(Class<?> type, Type genericType,  Annotation[] annotations, MediaType mediaType) {        return type == ZipInputStream.class;    }    @Override    public ZipInputStream readFrom(Class<ZipInputStream> type,  Type genericType, Annotation[] annotations, MediaType mediaType,  MultivaluedMap<String, String> httpHeaders,  InputStream entityStream) throws IOException, WebApplicationException {        return new ZipInputStream(entityStream);    }    }

然后,在您的资源方法中,您可以只具有一个

ZipInputStream
参数,而不是
InputStream

@POST@Consumes("application/zip")public Response postZipFile(ZipInputStream zip) throws Exception {

在客户端(使用客户端API),如果要使用

application/zip
,则当然还需要编写
MessageBodyWriter
for
application/zip


更新2

注释: 我需要我的方法能够使用一个简单的xml文件和一个包含xml文件的zip归档文件,因此我对方法进行了注释(伪代码):“
consumes(xml,zip)”并声明了一个参数InputStream的方法是;
然后,在方法主体中,我需要确定此InputStream是xml类型还是zip存档,并想要编写类似于以下内容:“
if(is属于xml类型){然后将其视为xml},否则{处理为a zip archive}。希望现在这个问题更容易理解

我们可以让您的原始方法签名接受

application/xml
application/zip
。我们也可以通过注入
HttpHeaders
Content-Type
从中获取来检查实际发送的是哪个。基于此,我们将确定如何提取。这是我们如何完成此操作的另一个示例

@Path("/zip")public class ZipResource {    @POST    @Consumes({"application/zip", "application/xml"})    public Response postZipFile(InputStream is, @Context HttpHeaders headers) throws Exception {        String contentType = headers.getHeaderString(HttpHeaders.CONTENT_TYPE);        String returnString = null;        if (null != contentType) switch (contentType) { case "application/xml":     returnString = readXmlFile(is);     break; case "application/zip":     returnString = readZipFile(is);     break;        }        return Response.ok(returnString).build();    }    private String filePartToString(InputStream is, int size) throws Exception {        String xml;        byte[] buff = new byte[size];        is.read(buff, 0, size);        return new String(buff);    }    private String readXmlFile(InputStream is) {        StringWriter writer = new StringWriter();        try { IOUtils.copy(is, writer, "utf-8");        } catch (IOException ex) { Logger.getLogger(ZipResource.class.getName()).log(Level.SEVERE, null, ex);        }        return writer.toString();    }    private String readZipFile(InputStream is) {        StringBuilder builder = new StringBuilder("==== Data ====n");        try (ZipInputStream zip = new ZipInputStream(is)) { ZipEntry entry; while ((entry = zip.getNextEntry()) != null) {     String filename = entry.getName();     if (filename.endsWith(".xml")) {         builder.append("name: ").append(entry.getName()).append("n");         String xml = filePartToString(zip, (int) entry.getSize());         builder.append("data: ").append(xml).append("n");     }     zip.closeEntry(); }        } catch (Exception ex) { ex.printStackTrace();        }        return builder.toString();    }}

我们将需要一个

MessageBodyReader
来处理
application/zip
类型。上面的一个很好用,但是我们只需要返回一个
InputStream
而不是
ZipInputStream

@Provider@Consumes("application/zip")public class ZipMessageBodyReader implements MessageBodyReader<InputStream> {    @Override    public boolean isReadable(Class<?> type, Type genericType,  Annotation[] annotations, MediaType mediaType) {        return type == InputStream.class;    }    @Override    public InputStream readFrom(Class<InputStream> type,  Type genericType, Annotation[] annotations, MediaType mediaType,  MultivaluedMap<String, String> httpHeaders,  InputStream entityStream) throws IOException, WebApplicationException {        return entityStream;    }  }

现在进行测试

@Testpublic void testResteasy() throws Exception {    WebTarget target = client.target( TestPortProvider.generateURL(base_URI)).path("zip");    File file = new File("C:/test/test.zip");    Response response = target.request().post( Entity.entity(file, "application/zip"));    System.out.println(response.getStatus());    System.out.println(response.readEntity(String.class));    response.close();    file = new File("C:/test/test1.xml");    response = target.request().post( Entity.entity(file, "application/xml"));    System.out.println(response.getStatus());    System.out.println(response.readEntity(String.class));    response.close();}

我们得到以下

200==== Data ====name: test1.xmldata: <test1>hello world</test1>name: test2.xmldata: <test2>hello squirrel</test2>200<test1>hello world</test1>

注意:
对于客户端,我必须实现一个

MessageBodyWriter
处理
application/zip
类型。以下是一个简单的实现,只是为了使测试生效。真正的实现需要一些修复

@Provider@Produces("application/xml")public class ZipClientMessageBodyWriter implements MessageBodyWriter<File> {    @Override    public boolean isWriteable(Class<?> type, Type genericType,  Annotation[] annotations, MediaType mediaType) {        return type == File.class;    }    @Override    public long getSize(File t, Class<?> type, Type genericType,  Annotation[] annotations, MediaType mediaType) {        return -1;    }    @Override    public void writeTo(File t, Class<?> type, Type genericType,  Annotation[] annotations, MediaType mediaType,  MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)  throws IOException, WebApplicationException {        IOUtils.write(IOUtils.toByteArray(new FileInputStream(t)), entityStream);    }  }....client.register(ZipClientMessageBodyWriter.class);

您还将在一些示例代码中注意到,我使用了Apache Commons

IOUtils
。不好意思 我很懒:-)


更新3

实际上,我们不需要

MessageBodyReader
。找到读者的算法其实只是默认为
InputStream
读者,因为它支持
application/xml
,所以它会已经返回
InputStream
我们是否有对读者
application/zip
还是不



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/509353.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号