Binding a Set of domain object in Grails command object - grails

I'm trying to bind a Set of objects to my Grails Command Objects, but currently, it doesn't work an throws errors:
Field error in object 'NewPersonCommand' on field 'addresses': rejected value [[Ljava.lang.String;#6d64b5fb]; codes [NewPersonCommand.addresses.typeMismatch.error,NewPersonCommand.addresses.typeMismatch,newPersonCommand.addresses.typeMismatch.error,newPersonCommand.addresses.typeMismatch,typeMismatch.NewPersonCommand.addresses,typeMismatch.addresses,typeMismatch.java.util.Set,typeMismatch]; arguments [addresses]; default message [Could not find matching constructor for: Address(java.lang.String)]>
I have the following command object in my Grails application:
class NewPersonCommand {
String name
Set<Address> addresses
}
And the code for the form I'm posting looks like this:
<input type="hidden" name="addresses" value="1" />
<input type="hidden" name="addresses" value="4" />
<input type="hidden" name="addresses" value="18" />
Any idea how I can fix this, so I can bind my set of addresses to the command object?

Related

Thymeleaf - Exception evaluating SpringEL expression on object variable

I am sticking a value into a hidden input with Thymeleaf and keep getting an error that says Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "receiptInquirySearchForm.cardNumber?:''" (template: "results.html" - line 14, col 44)
I have tried putting the ? after receiptInquirySearchForm, after cardNumber, and after both. I keep getting that same error on that line.
Here is line 14:
<input type="hidden" name="cardNumber" data-th-value="${receiptInquirySearchForm.cardNumber?}" />
Now I know receiptInquirySearchForm is a valid non-null object because I have several other hidden inputs that do not throw errors.
<input type="hidden" name="tokenId" data-th-value="${receiptInquirySearchForm.tokenId}" />
<input type="hidden" name="accountNumber" data-th-value="${receiptInquirySearchForm.accountNumber}" />
<input type="hidden" name="sku" data-th-value="${receiptInquirySearchForm.sku}" />
When I change the data-th-value from cardNumber to tokenId, it gets past that block of hidden inputs so every other line works fine.
UPDATE
I found another more descriptive error message down below.
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'cardNumber' cannot be found on object of type '...web.form.ReceiptInquirySearchForm' - maybe not public or not valid?
How can I check for that in the code? I know sometimes it will be there, but apparently in this instance it is not.
They were doing this in Velocity like this:
<input type="hidden" name="cardNumber" value="$!receiptInquirySearchForm.cardNumber" />
The exclamation correctly handled the possible missing or null cardNumber.
Just as #Metroids pointed out, you are probably missing getters/setters for the field cardNumber especially a getter for it. If you have a getter for it, check that the getter follows the POJO convention and is public like so;
public int getCardNumber()
{
return cardNumber;
}
If the spelling is not like so getCardNumber(), even though you can call the method in the controller to get the value, thymeleaf cannot do so because it relies on POJO convention to be able to call variable properties. I hope this helps.

Field not displayed with condition

I use thymeleaf 3
I try to use a condition with th:attr with some value
<input type="text" class="form-control" th:id="'genericForm'+${genericField.field}" th:attr="${genericField.mandatory} ? data-msg=#{mandatory.field}, name=${genericField.field} : name=${genericField.field}"/>
Actually, this input is not displayed
error is:
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as assignation sequence:
Any idea?
Like this is how I would do it:
<input type="text" class="form-control" th:id="'genericForm'+${genericField.field}" th:name="${genericField.field}" th:attr="${genericField.mandatory} ? data-msg=#{mandatory.field}"/>
You can move name out to th:name since it's in both.

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
}

Amazon S3 Upload via Post and ASP.NET MVC

I've been trying in vain for 2 days now to do a simple upload to my Amazon S3 Bucket. Below is my rendered form:
<form action="http://s3.amazonaws.com/MYBUCKETNAME" method="post" enctype="multipart/form-data">
<input type="hidden" name="AWSAccessKeyId" value="MYACCESSKEY" />
<input type="hidden" name="acl" value="private" />
<input type="hidden" name="key" value="UserUploads/TestUser/${filename}" />
<input type="hidden" name="success_action_redirect" value="http://WWW.MYURL.COM/" />
<input type="hidden" name="policy" value="POLICY" />
<input type="hidden" name="signature" value="SIGNATURE" />
<div>
Please specify a file, or a set of files:
<input type="file" name="file" size="100" />
</div>
<input type="submit" value="Upload" />
</form>
and my policy document looks like this:
{
expiration = "2011-12-08T12:00:00.000Z",
conditions = [
["eq","bucket","MYBUCKETNAME"],
["eq","acl","private"],
["starts-with","$key","UserUploads/TestUser/"],
["eq","success_action_redirect", "HTTP://WWW.MYURL.COM/"]
]
}
I get the following error:
Code: AccessDenied,
Message: Invalid according to Policy: Policy Condition failed: ["eq", "bucket", "MYBUCKETNAME"]
Does anyone have any ideas please, I'm grabbing at straws here. Also not sure if my Bucket Policy and ACL is correct.
According to http://doc.s3.amazonaws.com/proposals/post.html#Access_Control
Matching a Particular Value
Description: There are certain fields that you want to match a
particular value, such as matching a bucket name or requiring that an
object is uploaded using the public-read access control policy. The
field value is case sensitive, but the name is not.
Syntax: There are two ways to require that the field fieldname matches
the string value. The value is case sensitive. If the value starts
with a dollar sign ($), the dollar sign must be escaped with a
backslash (\$)
[ "eq", "$fieldname", "S" ],
(Note the $ prefix).
So your policy should have $ in sets where you using "eq" format
Why not do this in C# with the S3 SDK (http://aws.amazon.com/sdkfornet/), it's a bit more secure.
Here's my blog post with more detail: http://bradoyler.com/post/3614362044/uploading-an-image-with-aws-sdk-for-net-c.
Cheers and Good luck.
I was getting the following error:
Invalid according to Policy: Policy Condition failed: [\"eq\", \"$bucket\"
After many hours, I learned that you can't have a bucket with uppercase letters. Changing the bucket to lowercase fixed it.

Resources