Spring:JSON数据和文件在同一个请求中
我知道如何创建使用MediaType.MULTIPART_FORM_DATA
和@FormDataParam("file") FormDataBodyPart bodyPart
处理文件的端点@FormDataParam("file") FormDataBodyPart bodyPart
,但我想知道是否也可以在请求中包含JSON数据? 就像是:
@POST
@Path("somepath")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndJSON(@RequestBody SomeModel someModel,
@FormDataParam("file") FormDataBodyPart bodyPart) {
return null;
}
目前,如果我在下面的邮递员请求的“原始”选项卡上添加一些JSON数据,我得到HTTP 415 Unsupported Media Type
可能是因为我指定我使用MULTIPART_FORM_DATA
但我也使用了@RequestBody
,它正在寻找JSON内容是APPLICATION_JSON
。 那么如何让JSON数据和一个文件在同一个请求中处理呢? 我知道在两个请求中可以做到这一点,如果可能,我只想在一个请求中做到这一点?
你为什么使用Spring和Jersey注释? 你应该坚持使用框架的注释。 既然你在使用泽西岛,应该坚持它的注释。
所以这里是关于你当前的代码和环境要考虑的事情。
您可以将JSON作为多部分主体的一部分。 对于你也应该注释SomeModel
与泽西@FormDataParam
@POST
@Path("somepath")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndJSON(
@FormDataParam("model") SomeModel someModel,
@FormDataParam("file") FormDataBodyPart bodyPart) {
}
在Jersey配置中,您需要确保注册MultiPartFeature
。 如果你不这样做,身体将不能被反序列化,并且你会得到异常和错误响应。
现在邮差问题。 你可以在这里看到类似的问题。 问题在于未为JSON正文部分设置Content-Type
。 例如,身体可能看起来像
--AaB03x
Content-Disposition: form-data; name="model"
{"some":"model", "data":"blah"}
--AaB03x
Content-Disposition: form-data; name="file"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
如果您点击Postman中的预览按钮,您实际上可以看到身体。 问题是"model"
部分没有Content-Type
,如"file"
部分所示。 发生这种情况是因为您无法在邮递员中设置各个部分的Content-Type
。 你会看到的将从文件扩展名中被发现。 例如.txt
文件将使邮递员将Content-Type
设置为text/plain
并将.png
文件设置为image/png
。
如果你看看上面的链接,我建议也许你可以使用.json
文件而不是输入数据。 当然,那只是一个理论。 我没有真正测试它。
在任何情况下,必须设置Content-Type
才能使Jersey能够将其反序列化为JSON。 如果.json
文件扩展名理论没有出来,那么你可以使用不同的客户端,比如cURL,我在链接中展示了一个例子,或者你可以使用Jersey客户端来测试,如这里所见。
不要在Postman中将Content-Type
标题设置为multipart/form-data
。 它使用表单数据时为您设置。 我刚刚看到有人在设置标题时说有错误的帖子。 现在找不到帖子,也没有我确认的内容,但我只是将其忽略。
UPDATE
因此,OP能够找到一种将Content-Type: application/json
设置为“模型”部分的方法。 但有时用Javascript客户端的情况下,你无法设置它。 所以不会有Content-Type
。 如果是这样的话,Jersey将无法反序列化JSON,因为它不知道它实际上是发送了JSON。 如果您绝对不能或不知道如何为各个部分设置Content-Type
,则可以采取以下措施。
@POST
@Path("somepath")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndJSON(@FormDataParam("model") FormDataBodyPart jsonPart,
@FormDataParam("file") FormDataBodyPart bodyPart) {
jsonPart.setMediaType(MediaType.APPLICATION_JSON_TYPE);
SomeModel model = jsonPart.getValueAs(SomeModel.class);
}
是的,您可以将它作为多部分表单数据。
你在angularjs中得到这样的结果:
$scope.uploadFile = function () {
var file = $scope.selectedFile[0];
$scope.upload = $upload.upload({
url: 'api/upload',
method: 'POST',
data: angular.toJson($scope.model),
file: file
}).progress(function (evt) {
$scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total, 10);
}).success(function (data) {
//do something
});
};
$scope.onFileSelect = function ($files) {
$scope.uploadProgress = 0;
$scope.selectedFile = $files;
};
public Response uploadFileAndJSON(@RequestParam("data") String data,
@MultiPartFile("file")File file) {
you can data as form data and convert it
like you want to your object using Gson jar.
return null;
}
看看它的angularjs代码:Angularjs如何上传多部分表单数据和文件?
https://puspendu.wordpress.com/2012/08/23/restful-webservice-file-upload-with-jersey/
链接地址: http://www.djcxy.com/p/48635.html