{"id":4512,"date":"2011-11-18T19:17:50","date_gmt":"2011-11-18T13:47:50","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=4512"},"modified":"2017-03-20T17:05:11","modified_gmt":"2017-03-20T11:35:11","slug":"uploading-multiple-files-with-same-name","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/uploading-multiple-files-with-same-name\/","title":{"rendered":"uploading multiple files with same name"},"content":{"rendered":"<p>A good binding feature in grails is that when you have multiple input fields with same name, they are available as a list in <code>params<\/code>. But this does not hold with html file input fileds. If you have multiple file input fields with same name, <code>params.fieldName<\/code> will not return a list but the first input field with name <code>fieldName<\/code>.  This is due to using <code>fileMap<\/code> attribute of <code>request<\/code> object. Here is the relevant part of <code>GrailsParameterMap<\/code> class(I suspected this class because of <code>params.getClass()<\/code> returned <code>GrailsParameterMap<\/code>) : <\/p>\n<p>[groovy]<br \/>\n    GrailsParameterMap(HttpServletRequest request) {<br \/>\n\t\/\/&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n        if (request instanceof MultipartHttpServletRequest) {<br \/>\n            def fileMap = request.fileMap<br \/>\n            for (fileName in fileMap.keySet()) {<br \/>\n                requestMap.put(fileName, request.getFile(fileName))<br \/>\n            }<br \/>\n        }<br \/>\n\t\/\/&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n    }<br \/>\n[\/groovy]<br \/>\nDue to above implementation, If you have three file input fields with name <code>familyPics<\/code>, only the first one will be available via <code>params.familyPics<\/code> of type <code>CommonsMultipartFile<\/code>. <\/p>\n<p>\nIn one of the mail thread(links at the end of the blog), I got to know that grails uses <em>Spring 3.0<\/em> starting from <em>grails version 1.2<\/em> which supports <code>multiFileMap<\/code> attribute in <code>request<\/code> object. Using this attribute you can access multiple files from inputs with the same name (or that uses the <em>HTML5<\/em> multiple attribute). So if the implementation is changed to something like :<br \/>\n[groovy]<br \/>\n   GrailsParameterMap(HttpServletRequest request) {<br \/>\n\t\/\/&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n        if (request instanceof MultipartHttpServletRequest) {<br \/>\n                    def multipleFileMap = request.multiFileMap<br \/>\n\/* instead of using fileMap. However this map value is always a list even if there is only one file input for a name *\/<br \/>\n                    multipleFileMap.each {fieldName, files -&amp;amp;gt;<br \/>\n                        if (files.size() == 1) {<br \/>\n                            requestMap.put(fieldName, files.first())<br \/>\n\/* Make this available as a single element instead of list, if the user wants he can use params.list(&#8216;fieldName&#8217;) for list version *\/<br \/>\n                        } else {<br \/>\n                            requestMap.put(fieldName, files)<br \/>\n                        }<br \/>\n                    }<br \/>\n        }<br \/>\n\t\/\/&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n    }<br \/>\n[\/groovy]<br \/>\nThen if there are three file input fields with name <code>familyPics<\/code>, then <code>params.familyPics<\/code> will return a list of <code>CommonsMultipartFile<\/code> objects. If there is only one file input field with name <code>profilePic<\/code> then <code>params.profilePic<\/code> will return an object of type <code>CommonsMultipartFile<\/code> and <code>params.list('profilePic')<\/code> will return a list of <code>CommonsMultipartFile<\/code> objects.<\/p>\n<p style='padding-bottom:20px;'>\n<p>This feature can be added using <em>Groovy\/Grails MetaProgramming<\/em>(Until grails is updated for this feature). However I went with <em>Grails Filter<\/em> solution. Create\/update a filter with this entry :\n<\/p>\n<p>[groovy]<br \/>\n        multipartFileSupport(controller: &#8216;*&#8217;, action: &#8216;*&#8217;) {<br \/>\n            before = {<br \/>\n                if (request instanceof MultipartHttpServletRequest) {<br \/>\n                    def multipleFileMap = request.multiFileMap<br \/>\n                    multipleFileMap.each {fieldName, files -&amp;amp;gt;<br \/>\n                        if (files.size() == 1) {<br \/>\n                            params.put(fieldName, files.first())<br \/>\n                        } else {<br \/>\n                            params.put(fieldName, files)<br \/>\n                        }<br \/>\n                    }<br \/>\n                }<br \/>\n            }<br \/>\n        }<br \/>\n[\/groovy]<\/p>\n<p>Now inside any controller\/action you can access statements like(even grails auto binding will work fine) :<br \/>\n[groovy]<br \/>\n\/* Suppose there is a file input field with name profilePic *\/<br \/>\nCommonsMultipartFile profilePic=params.profilePic<br \/>\nList&amp;amp;lt;CommonsMultipartFile&amp;amp;gt; profilePicAsList=params.list(&#8216;profilePic&#8217;)<\/p>\n<p>\/* Suppose there are three file input fields with same name familyPics *\/<br \/>\nList&amp;amp;lt;CommonsMultipartFile&amp;amp;gt; familyPics=params.familyPics<br \/>\n[\/groovy]<\/p>\n<p>Hope this feature will be available soon in grails without having to write filters or doing meta programming.<\/p>\n<p style='padding-bottom:20px;'>\n<p>Helpful links : <\/p>\n<p><a href=\"http:\/\/stackoverflow.com\/questions\/3710232\/how-to-iterate-over-uploaded-files-in-grails\">http:\/\/stackoverflow.com\/questions\/3710232\/how-to-iterate-over-uploaded-files-in-grails<\/a><\/p>\n<p><a href=\"http:\/\/forum.springsource.org\/showthread.php?44632-CommonsMultipartResolver-Uploading-many-files-with-same-html-name\">http:\/\/forum.springsource.org\/showthread.php?44632-CommonsMultipartResolver-Uploading-many-files-with-same-html-name<\/a>\n<\/p>\n<p style='padding-bottom:20px;'>\n<p>~~~~~~Cheers~~~~~~~<br \/>\nBhagwat Kumar<br \/>\nbhagwat(at)intellligrape(dot)com<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Grails does not support accessing multiple file input fields with same name using params.fieldName. We need to use request.multiFileMap (available in Spring 3.0) instead of request.fileMap. The blog provides sample code to achieve this feature via Grails Filter.<\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":10},"categories":[7],"tags":[684,686,636,685,687,688],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/4512"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=4512"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/4512\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=4512"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=4512"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=4512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}