在单个http请求中使用与每个文件相关的元数据进行多文件上传 [英] Multi file upload with metadata with relation to every file in a single http request

查看:348
本文介绍了在单个http请求中使用与每个文件相关的元数据进行多文件上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个服务(前端和后端),允许将多个文件和元数据上传到每个文件,这样我就可以生成一个特定的路径来保存文件。 (元数据会给我所有关于路径的信息)。此外,请求将包含需要保存到数据库(这部分工作正常)的信息,所以它的所有事务。所以我唯一不知道的是如何发送和接受每个文件的元数据。
$ b

前端:Angularjs

后端:Groovy / Java,Spring 3.0

  @RequestMapping(value =/ view /单个/多个文件,method = POST,产生= APPLICATION_JSON_VALUE)
def createNewAdjustment(@RequestParam(files)List< List< MultipartFile>>文件,
@RequestParam(data) List< DataRequest> data){}

所以在上面的代码中:

   - 列表清单:是需要处理和保存的文件。 
- 数据:是需要处理,保存并与文件互连的对象列表。

请求有效载荷如下所示:

  ------ WebKitFormBoundaryPve8x58T1pAIsQOS 
Content-Disposition:form-data; name $ data

{rollNumber:1111111111111,compId:213131,adjId:260b018c-5921-4c1c-aa99-ba8587ee4777}
- ---- WebKitFormBoundaryPve8x58T1pAIsQOS
Content-Disposition:form-data; NAME = 文件; filename =some.json.gz
Content-Type:application / x-gzip


------ WebKitFormBoundaryPve8x58T1pAIsQOS
Content-Disposition:form -数据; NAME = 文件; filename =someother.csv.gz
Content-Type:application / x-gzip


------ WebKitFormBoundaryPve8x58T1pAIsQOS--

您可以看到'name:file'重复2次,我不确定如何手动设置或/和附加更多的请求。任何想法?

解决方案

我发现这个解决方案:



所以从前端(AngularJS):

  $ upload.upload({
url:'upload' ,
headers:{'myHeaderKey':'myHeaderVal'},
data:{
myModel:$ scope.myModel,$ b $ array:[1,2,3]
$,
formDataAppender:function(fd,key,val){
if(angular.isArray(val)){
angular.forEach(val,function(v){
fd.append(key,v);
});
} else {
fd.append(key,val);
}
},
file:$ file,
fileFormDataName:'myFile'
})



< formDataAppender会为请求添加一个新的部分,您可以为每个发送的文件自定义名称。 (正是需要的)。

从后端(Spring Groovy):

 $ 
ResponseEntity< String> docsUpload(HttpServletRequest request,@RequestParam(data)String data)throws IOException {
MultipartHttpServletRequest multipartRequest =(MultipartHttpServletRequest)request
List< List< MultipartFile>> files = new ArrayList< List< MultipartFile>>()
multipartRequest.getFileNames()。each {
files.add(multipartRequest.getFiles(it))
}
PoJoObject pojoObject = mapper.readValue(data,PoJoObject)

files.each {def it - >
it.each {def itf - >
log.debug(itf.originalFilename)//实际文件的名称
log.debug(itf.name)// formDataAdapter的自定义字段

// in在这里你可以处理'PoJoObject'中的每个字段,并使
与文件

}

返回null;

$ / code $


这个解决方案适用于我,解决了我的问题:)现在我可以将数据和相应的文件保存在一个请求中。


I'm working on a service (front-end and back-end) that will allow to upload multiple files and metadata to every file, so I will be able to generate a specific path to save the files. (metadata will give me all the information about the path). Also, the request will contain information that needs to be saved to DB (this part is working fine), so its all transactional. So the only thing that I can't figure out is how to send and accept metadata to every file.

Front-end: Angularjs

Back-end: Groovy/Java, Spring 3.0

@RequestMapping(value = "/view/single/multi-file", method = POST, produces = APPLICATION_JSON_VALUE)
def createNewAdjustment(@RequestParam("files") List<List<MultipartFile>> files,
                        @RequestParam("data") List<DataRequest> data){}

So in the code above:

- the list of lists: are the files that needs to be processed and saved.
- the data: is the list of objects that needs to be processed,saved and interconnect them with files.

The request payload looks like this:

------WebKitFormBoundaryPve8x58T1pAIsQOS
Content-Disposition: form-data; name="data"

{"rollNumber":"1111111111111","compId":213131,"adjId":"260b018c-5921-4c1c-aa99-ba8587ee4777"}
------WebKitFormBoundaryPve8x58T1pAIsQOS
Content-Disposition: form-data; name="files"; filename="some.json.gz"
Content-Type: application/x-gzip


------WebKitFormBoundaryPve8x58T1pAIsQOS
Content-Disposition: form-data; name="files"; filename="someother.csv.gz"
Content-Type: application/x-gzip


------WebKitFormBoundaryPve8x58T1pAIsQOS--

You can see 'name: "file"' repeats 2 times and I'm not sure how to set it manually or/and attach more into to the request. Any ideas ?

解决方案

I found the solution to this :)

So from the front-end (AngularJS):

$upload.upload({
    url : 'upload',
    headers: {'myHeaderKey': 'myHeaderVal'},
    data : {
        myModel : $scope.myModel,
        array: [1,2,3]
    },
    formDataAppender: function(fd, key, val) {
        if (angular.isArray(val)) {
            angular.forEach(val, function(v) {
                fd.append(key, v);
            });
        } else {
            fd.append(key, val);
        }
    },
    file : $file,
    fileFormDataName: 'myFile'
})

formDataAppender will add a new part to the request and you can customize the name for every single file you are sending. (exactly what is needed).

From the back-end (Spring Groovy):

@Autowired DbRepository dbRepo
@RequestMapping(value = "/docs/upload", method = POST)
ResponseEntity<String> docsUpload(HttpServletRequest request, @RequestParam("data") String data) throws IOException {
    MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request
    List<List<MultipartFile>> files = new ArrayList<List<MultipartFile>>()
    multipartRequest.getFileNames().each {
        files.add(multipartRequest.getFiles(it))
    }
    PoJoObject pojoObject = mapper.readValue(data, PoJoObject)

    files.each { def it ->
      it.each { def itf ->
        log.debug(itf.originalFilename) // the name of the actual file
        log.debug(itf.name) // the custimized field from formDataAdapter

        // in here you can process every field in 'PoJoObject' and make
        // relation to the the file
      }
    }

    return null;
}

This solution works for me and solves the issue I had :) Now I can save data and corresponding files transactionally in a single request.

这篇关于在单个http请求中使用与每个文件相关的元数据进行多文件上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆