n3o*_*n3o 4 cxf inputstream multipart
我正在尝试使用Apache CXF开发API调用,该调用接收附件以及请求.我遵循了这个教程,这是我到目前为止所得到的.
@POST
@Path("/upload")
@RequireAuthentication(false)
public Response uploadWadl(MultipartBody multipartBody){
List<Attachment> attachments = multipartBody.getAllAttachments();
DataHandler dataHandler = attachments.get(0).getDataHandler();
try {
InputStream is = dataHandler.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return Response("OK");
}
Run Code Online (Sandbox Code Playgroud)
我正在获取附件的InputStream对象,一切正常.但是,我需要将附件作为java.io.File对象传递给另一个函数.我知道我可以在这里创建一个文件,从输入流中读取并写入它.但是有更好的解决方案吗?CXF是否已将其存储为文件?如果是这样,我可以继续使用它.有什么建议?
Bri*_*ice 13
我也对此事感兴趣.在与CXF邮件列表上的Sergey讨论时,我了解到如果附件超过某个阈值,CXF正在使用临时文件.
在这个过程中,我发现了这篇博文,解释了如何安全地使用CXF附件.您也可以对此页面上的示例感兴趣.
这就是我现在正在调查的所有内容,我希望这有帮助.
编辑:目前我们处理CXF 2.6.x的附件.关于使用多部分内容类型上载文件.
在我们的REST资源中,我们定义了以下方法:
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/")
public Response archive(
@Multipart(value = "title", required = false) String title,
@Multipart(value = "hash", required = false) @Hash(optional = true) String hash,
@Multipart(value = "file") @NotNull Attachment attachment) {
...
IncomingFile incomingFile = attachment.getObject(IncomingFile.class);
...
}
Run Code Online (Sandbox Code Playgroud)
关于该片段的一些注释:
@Multipart 不是JAXRS的标准,它甚至不是JAXRS 2,它是CXF的一部分.MultipartBody,这里的关键是使用类型的参数Attachment所以是的,据我们所知,还没有可能在方法签名中直接得到我们想要的类型.因此,例如,如果您只是想要InputStream附件,则无法将其放在方法的签名中.您必须使用该org.apache.cxf.jaxrs.ext.multipart.Attachment类型并编写以下语句:
InputStream inputStream = attachment.getObject(InputStream.class);
Run Code Online (Sandbox Code Playgroud)
我们在Sergey Beryozkin的帮助下发现我们可以转换或包装它InputStream,这就是为什么我们在上面的代码片段中写道:
IncomingFile incomingFile = attachment.getObject(IncomingFile.class);
Run Code Online (Sandbox Code Playgroud)
IncomingFile是我们的自定义包装器InputStream,因为你必须注册一个MessageBodyReader,ParamHandler不会有帮助,因为他们不使用流而是使用String.
@Component
@Provider
@Consumes
public class IncomingFileAttachmentProvider implements MessageBodyReader<IncomingFile> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type != null && type.isAssignableFrom(IncomingFile.class);
}
@Override
public IncomingFile readFrom(Class<IncomingFile> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream
) throws IOException, WebApplicationException {
return createIncomingFile(entityStream, fixedContentHeaders(httpHeaders)); // the code that will return an IncomingFile
}
}
Run Code Online (Sandbox Code Playgroud)
但请注意,已经进行了一些试验,以了解传递的内容,方法和热修复错误的方法(例如,附件部分的第一个标题的第一个字母是吃的,所以你有ontent-Type而不是Content-Type).
当然,它entityStream代表InputStream了附件的实际情况.此流将从内存或磁盘读取数据,具体取决于CXF放置数据的位置; 这个问题有一个大小阈值属性(attachment-memory-threshold).您还可以说临时附件将去哪里(attachment-directory).
只是不要忘记在完成后关闭流(一些工具为你做).
一旦一切都被配置我们用测试它休息保证的,从约翰·Haleby.(有些代码是我们测试工具的一部分):
given().log().all()
.multiPart("title", "the.title")
.multiPart("file", file.getName(), file.getBytes(), file.getMimeType())
.expect().log().all()
.statusCode(200)
.body("store_event_id", equalTo("1111111111"))
.when()
.post(host().base().endWith("/store").toStringUrl());
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要以这种方式通过curl上传文件:
curl --trace -v -k -f
--header "Authorization: Bearer b46704ff-fd1d-4225-9dd4-e29065532b73"
--header "Content-Type: multipart/form-data"
--form "hash={SHA256}3e954efb149aeaa99e321ffe6fd581f84d5a497b6fab5c86e0d5ab20201f7eb5"
--form "title=fantastic-video.mp4"
--form "archive=@/the/path/to/the/file/fantastic-video.mp4;type=video/mp4"
-X POST http://localhost:8080/api/video/event/store
Run Code Online (Sandbox Code Playgroud)
为了完成这个答案,我想提一下,有可能在多部分中使用JSON有效负载,因为你可以Attachment在签名中使用一个类型然后写
Book book = attachment.getObject(Book.class)
Run Code Online (Sandbox Code Playgroud)
或者你可以写一个像这样的论点:
@Multipart(value="book", type="application/json") Book book
Run Code Online (Sandbox Code Playgroud)
Content-Type在执行请求时,不要忘记将标题添加到相关部分.
值得一提的是,可以在列表中包含所有部分,只需使用单个参数类型编写方法即可List<Attachment>.但是我更喜欢在方法签名中使用实际参数,因为它更清晰,更少样板.
@POST
void takeAllParts(List<Attachment> attachments)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15306 次 |
| 最近记录: |