IncomingFile is our custom wrapper around the InputStream, for that you have to register a MessageBodyReader, ParamHandler won't help as they don't work with streams but with String.@Component@Provider@Consumespublic 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 }}但是请注意,已经进行了一些试验来了解通过了什么,如何以及如何修复错误(例如,附件部分第一个标头的第一个字母被吃掉了,所以您有ontent-Type代替Content-Type).Note however that there have been a few trials to understand what was passed, how, and the way to hot-fix bugs (For example the first letter of the first header of the attachment part was eat so you had ontent-Type instead of Content-Type).当然,entityStream代表附件的实际InputStream.该流将从内存或磁盘读取数据,具体取决于CXF将数据放在何处;对此有一个大小阈值属性(attachment-memory-threshold).您还可以说出临时附件的位置(attachment-directory).Of course the entityStream represents the actual InputStream of the attachment. This stream will read data either from memory or from disk, depending on where CXF put the data ; there is a size threshold property (attachment-memory-threshold) for that matter. You can also say where the temporary attachments will go (attachment-directory).请别忘了在完成操作后关闭流(某些工具会帮您完成该操作).Just don't forget to close the stream when you are done (some tool do it for you).配置完所有内容后,我们将使用中的 Rest-Assured 对其进行测试Johan Haleby . (尽管有些代码是我们的测试实用程序的一部分):Once everything was configured we tested it with Rest-Assured from Johan Haleby. (Some code are part of our test utils though) :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());或者如果您需要通过curl通过这种方式上传文件:Or if you need to upload the file via curl in such a way :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要完成此答案,我想提到可以将JSON有效负载分为多个部分,因为您可以在签名中使用Attachment类型,然后编写To finish this answer, I'd like to mention it is possible to have JSON payload in multipart, for that you can use an Attachment type in the signature and then writeBook book = attachment.getObject(Book.class)或者您可以编写一个类似Or you can write an argument like :@Multipart(value="book", type="application/json") Book book执行请求时,别忘了将Content-Type标头添加到相关部分.Just don't forget to add the Content-Type header to the relevant part when performing the request.也许值得一提的是,可以将所有部分都包含在列表中,只需编写一个具有List<Attachment>类型的单个参数的方法即可.但是,我更喜欢在方法签名中包含实际参数,因为它更干净,样板更少.It might be worth to say that it is possible to have all the parts in a list, just write a method with a single argument of type List<Attachment>. However I prefer to have the actual arguments in the method signature as it's cleaner and less boilerplate.@POSTvoid takeAllParts(List<Attachment> attachments) 这篇关于在CXF API中处理多部分附件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-05 05:21