Jersey 2:发送包含信息和文件的多部分

hue*_*ami 5 rest client multipart jersey-2.0

我想编写一个 Java REST 客户端,上传包含一些信息的 json 文件。Web 服务的描述指出必须使用 MultiPart。不幸的是,我在网上找到的解决方案并不适合我。

网络服务描述指出:

  • 多部分
    • ContentDispositionHeader: 表单数据名称 = "\ObjectInfo"\
      • 文件类型记录 ID:字符串
      • 由用户创建更新:字符串
      • 实际文件名:字符串
    • ContentDispositionHeader:表单数据名称=文件名
      • 文件多部分数据

我的代码如下:

    Client client = ClientBuilder.newBuilder()
        .register(MultiPartFeature.class)
        .build();
    WebTarget target = client.target(Uri);  

    MultivaluedMap<String, String> info = new MultivaluedHashMap<String, String>();
    info.add("FileTypeRecId", scheduleGuid);
    info.add("CreatedUpdatedBy", user);
    info.add("actualFileName", scheduleFileName);
    Gson g = new Gson();
    String infoString = g.toJson(info, MultivaluedMap.class);

    try {
        (new BufferedWriter(new FileWriter(scheduleFileName))).write(scheduleJson);
    } catch (IOException e) {
        e.printStackTrace();
    }
    FileDataBodyPart fileDataBodyPart = new FileDataBodyPart();
    fileDataBodyPart.contentDisposition(FormDataContentDisposition.name(scheduleFileName).build());
    fileDataBodyPart.setFileEntity(new File(scheduleFileName), MediaType.APPLICATION_JSON_TYPE);

    MultiPart multiPart = new MultiPart();
    multiPart.bodyPart(infoString, MediaType.APPLICATION_JSON_TYPE);
    multiPart.bodyPart(fileDataBodyPart, fileDataBodyPart.getMediaType());
    multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE);

    Response response = target.request(MediaType.APPLICATION_JSON_TYPE)
        .header("Authorization", "xxx")
        .post(Entity.entity(multiPart, multiPart.getMediaType()));
Run Code Online (Sandbox Code Playgroud)

post方法中抛出的异常:

Exception in thread "main" javax.ws.rs.ProcessingException: No available MessageBodyWriter for class "class org.glassfish.jersey.media.multipart.file.FileDataBodyPart" and media type "multipart/form-data".
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:254)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:671)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:668)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:668)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:428)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:334)
at  ...
at  ...
Caused by: java.lang.IllegalArgumentException: No available MessageBodyWriter for class "class org.glassfish.jersey.media.multipart.file.FileDataBodyPart" and media type "multipart/form-data".
at org.glassfish.jersey.media.multipart.internal.MultiPartWriter.writeTo(MultiPartWriter.java:229)
at org.glassfish.jersey.media.multipart.internal.MultiPartWriter.writeTo(MultiPartWriter.java:79)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:502)
at org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:329)
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:242)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:245)
... 11 more
Run Code Online (Sandbox Code Playgroud)

下面是 C++ 客户端示例的代码片段:

QFileInfo fileInfo(uploadFilePath);

QVariantMap InfoJSON;
InfoJSON.insert("FileTypeRecId", filetypeid);
InfoJSON.insert("CreatedUpdatedBy", "nm");
InfoJSON.insert("actualFileName", fileInfo.fileName());
QJsonDocument doc= QJsonDocument::fromVariant(InfoJSON);

QHttpPart infoPart;
infoPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"ObjectInfo\""));
infoPart.setBody(doc.toJson());

QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\""+ fileInfo.baseName() + "\"; filename=\""+ fileInfo.fileName() + "\""));
QFile *file = new QFile(uploadFilePath);
file->open(QIODevice::ReadOnly);
filePart.setBodyDevice(file);

file->setParent(multiPart);

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
multiPart->append(infoPart);
multiPart->append(filePart);
Run Code Online (Sandbox Code Playgroud)

有人知道我做错了什么吗?