Send file to server in grails 3.0.0.1 - grails

I'm doing some test with grails 3.0.0.M1 and I have a form that sends a file to server using :
In view:
<g:uploadForm controller="file" action="upload">
<input type="file" name="file" />
<input type="submit" value="send"/>
</g:uploadForm>
and In the controller I have:
def file() {
def f = request.getFile("file")
//....some code
}
With f I have a NullPointerException that is to say the server don't receive the file from the view.
How how I can fix it?
Thanks!

There were some issues in Grails 3.0.0 M1 regarding file uploads, please try 3.0.0 RC2

Related

Amazon s3 form post/upload redirecting to bucket after success on iOS safari/chrome only how to stop?

I have a web app that allows users to upload photos to an S3 bucket via HTML form. It works exactly as expected on all desktop browsers, which is to do nothing after a successful upload. However in iOS safari and iOS chrome, it redirects to the bucket. If I "Handoff" the page over to safari on my mac it is an xml response of the entire bucket, it appears.
Does anyone know why this would happen and how to fix it? Normally I can find something via google and the forums but I'm finding nothing!
We are not specifying "success action redirect" or "success action status" on our form.
Also, it works as expected in chrome on an android device.
We do not want any sort of redirect to occurs, we handle things on the client after clicking the submit/post button.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<div id ="mainContent">
<form action="https://s3.amazonaws.com/{!awsKeySet.Name}" method="post" enctype="multipart/form-data" id="uploadForm">
<input type="hidden" name="key" id="key" />
<input type="hidden" name="AWSAccessKeyId" value="{!awsKeySet.AWS_AccessKey_Id__c}" />
<input type="hidden" name="policy" value="{!policy}" />
<input type="hidden" name="signature" value="{!signedPolicy}" />
<input type="hidden" name="acl" value="{!acessType}" />
<input type="hidden" name="Content-Type" value="{!Content_Type}" />
<!--input type="hidden" name="success_action_status" value="201" /-->
<!--input type="hidden" name="success_action_redirect" value="{!ForRedirect}" /-->
<h4 class="fileToUpload">Select a File to Upload in AWS</h4><br />
<div class="row">
<input type="file" size="50" name="file" id="file" />
</div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div class="row">
<input type="submit" value="Upload" id="btn_submit" />
</div>
<div id="progressNumber"></div>
</form>
</div>
<script>
$(document).ready(function () {
var _requestBucket;
$("#btn_submit").click(function(event){
//alert(1);
event.preventDefault();
var _file;
_file = $("#file").val().replace(/.+[\\\/]/, "");
console.log('_file '+ _file);
$("#key").val(_file);
$("#uploadForm").submit();
});
});
</script>
Thank you!
I wish someone could have shed more light on this but sadly, this is a bug in iOS webkit browsers. It appears to have been fixed in Android and Desktop. So, if anyone stumbles on this problem, included is the bugzilla link for it
Bugzilla link for Proper handling of HTTP 204
More detail : According to the amazon s3 docs
If the value is set to 200 or 204, Amazon S3 returns an empty document with a
200 or 204 status code.
If the value is set to 201, Amazon S3 returns an XML document with a
201 status code.
If the value is not set or if it is set to an invalid value, Amazon S3
returns an empty document with a 204 status code.
According to HTTP 1.1 -
10.2.5 204 No Content
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
If the client is a user agent, it SHOULD NOT change its document view
from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
This is not happening in either webkit browsers for iOS, currently. Sadly. I cannot find a way around this, other for Apple to fix it!

How to upload file to FTP Server in grails

I've read the answers to the question asked here :
How to upload file to remote FTP Server in grails
everything compiles and runs without errors. Now how do I reference the upload service from a Grails form? Sorry for the basic question.
So far I'm playing around with
<g:form action="do_something" enctype="multipart/form-data" useToken="true">
<span class="button">
<input type="file" name="thefile"/>
<input type="submit" class="upload" value="upload"/>
</span>
</g:form>
but I just need a few pointers as to how to link this with the service, presumably via the controller.
Work with the request. Get the file name and create a new file. my own code:
def f = request.getFile('myfile');
def webrootDir = servletContext.getRealPath("/"); //app directory
File fileDest = new File(webrootDir,"xmls/");
def xmlFile = new File(fileDest, "settings.xml");
f.transferTo(xmlFile);
Just look at this post for more info.

File upload & Spring Security

Based on the Spring Security documentation, I setup a MultipartFileter as the following:
#Order(1)
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
In a file upload form, I can see a CSRF input with a not-null value in a HTML file (see the code below).
<form method="POST" enctype="multipart/form-data" action="/upload">
File to upload: <input type="file" name="file" /><br />
Name: <input type="text" name="name" /><br /> <br />
<input type="submit" value="Upload" />
Press here to upload the file!
<input type="hidden" name="_csrf" value="df94be7d-675d-428c-89e5-2ebf0b473c42" />
</form>
After submitting the form, I get an error as
HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
type Status report
message Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
description Access to the specified resource has been forbidden.
What is missing here?
This problem is resolved after changing the Java configuration of the application. The followings are those changes.
In AbstractAnnotationConfigDispatcherServletInitializer class, I add the MultipartFilter in the getServletFilters method and set the MultipartConfig with a MultipartConfigElement in customizeRegistration(ServletRegistration.Dynamic registration) method. A MutlipartConfigElement originally defined in WebMvcConfigurerAdapter class is removed. And a MultipartResolver defined in the class is unchanged.
The Java configuration was set up based on the original XML configuration of the application. The approach doesn't always work based on this case.

Grails and form input multiple

I didn't find the part about this in the documentation, so I will be very happy if someone can help me =)
I have this form on my page to upload multiple pictures, using multiple for my input:
<g:uploadForm controller="photo" action="add" autocomplete="off">
<label for="files">Files to upload:</label>
<input type="file" id="files" name="files" multiple="multiple" />
<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />
<g:submitButton name="add" class="save button medium" value="ADD" />
</g:uploadForm>
And now, I don't know how to "separate" files in my controller.
It is ok for one file, using request.getFile(..), but how can I handle the "multiple" property of my field ?
Thanks for reading,
Alexandre
You can do this within your controller:
List fileList = request.getFiles('files') // 'files' is the name of the input
fileList.each { file ->
println 'filename: ' + file.getOriginalFilename()
}
request.getFiles(<param>) returns a list of CommonsMultipartFile objects. You can use these objects to get the file names (like in the example) or the file content (file.getInputStream())
You got the answer, but this just for a record
request.multiFileMap?.each { name, map ->
//do the logic
}

Grails multi-part form server 500 error on null object when deployed, but not on local host

In my grails project I have a multipart-form that grabs the file and assigns the filename to a variable that gets stored in the database.
When I run the app from localhost with production flag I am able to successfully submit the form, however, after I deploy the app to a glassfish server, I get a server 500 error:
Cannot get property 'originalFilename' on null object
I am thinking that maybe it has something to do with not handling multipart correctly. Anyone have this issue or can point me in the right direction to solving it?
Using Grails 2.0.4 deployed to Glassfish 3 server using Oracle db.
pertinent code from my action:
def uploadedFile = request.getFile('filepath')// see if there is a file to upload
if (!uploadedFile?.empty) { // is there a file?
sampleInstance.filepath = "file://///FileLocation/${uploadedFile?.originalFilename}" // save the original filename
}
Form on gsp:
<g:form action="sample" enctype="multipart/form-data">
<g:textField name="name" value="${sampleInstance?.name}"/>
...
<input type="file" id="filepath" name="filepath" />
<g:submitButton name="submit" value="Submit" /></td>
</g:form>
If uploadedFile is null, then uploadedFile?.empty will be null, so
if (!uploadedFile?.empty) { // is there a file?
Will do the opposite of what you are expecting
You should probably be doing
if ( uploadedFile && !uploadedFile.empty) { // is there a file?

Resources