Spring controller get empty object - java

I'm sending an object to spring controller via jsp form.
JSP:
<form:form modelAttribute="uploadItem" action="/uploadObject" method="post" enctype="multipart/form-data">
<form:input path="fileData" accept="audio/mpeg" type="file" id="file-upload" name="file-upload" />
<form:input type="text" path="title" id="upload-title" name="upload-title"/>
<input type="image" src="..." alt="Upload"/>
</form:form>
ModelService:
public void fillUploadMelodyModel(Model model) {
fillAdminRootModel(model);
model.addAttribute("uploadItem", new UploadedItem());
}
UploadedItem:
public class UploadedItem {
private CommonsMultipartFile fileData;
private String title;
}
Controller:
#RequestMapping(value = "/uploadObject", method = RequestMethod.POST)
public String doUpload(UploadedItem uploadItem, BindingResult result, Principal principal) {
//at this point I get an empty object (null null values)
}
What is the problem? How to pass object to controller in jsp?

Try changing then your controller like this
#RequestMapping(value = "/uploadObject", method = RequestMethod.POST)
public String doUpload(UploadedItem uploadItem,
BindingResult result,
#RequestParam("fileData") MultipartFile file,
#RequestParam("title") String title,
Principal principal) {
//Here you should receive your parameters
}

I think the names you have used for the file (file-upload) and title (upload-title) are not in sync with your domain object attribute names. Change your names to fileData and title in your Jsp page.

Related

Spring RestController POST accepting a basic HTML form

I'm attempting to post a simple HTML form to Spring RestController using #ModelAttribute and MediaType.APPLICATION_FORM_URLENCODED_VALUE as consumed data type. I've double checked all of my forms fields which match my request bean.
When the request enters the mapped method, all of the request beans fields are null.
#RestController
#EnableWebMvc
public class WebServiceController {
#RequestMapping(
value = "/test",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<?> post(#ModelAttribute FormBean request){
// request.getParam() == null
return ResponseEntity.ok().build();
}
}
public class FormBean {
private String param1;
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}
}
<html>
<head>
<title>Test Form</title>
</head>
<body>
<form action="/test" method="POST">
<input type="text" id="param1">
<button type="submit">Submit</button>
</form>
</body>
</html>
You are missing the name attribute in your HTML inputs, id attribute is meaningless when posting an HTML form
<input type="text" name="param1">

Invalid property 'redeemVoucherForm' of bean class [my.testapp.forms.RedeemVoucherForm]

I'm getting an error:
Invalid property 'redeemVoucherForm' of bean class [my.testapp.forms.RedeemVoucherForm]: Bean property 'redeemVoucherForm' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
RedeemVoucherForm.java:
package my.testapp.forms;
public class RedeemVoucherForm {
private String voucherCode;
public String getVoucherCode() {
return voucherCode;
}
public void setVoucherCode(String voucherCode) {
this.voucherCode = voucherCode;
}
}
In my PageController.java, I'm adding model redeemVoucherForm, which exist, when I call method model.containsAttribute("redeemVoucherForm"):
#RequestMapping(method = RequestMethod.GET)
public String showPage(final Model model) {
...
model.addAttribute("redeemVoucherForm", new RedeemVoucherForm());
...
return REDIRECT_PAGE_URL;
}
#RequestMapping(value = "/redeem-voucher", method = RequestMethod.POST)
public String redeemVoucher(#Valid final RedeemVoucherForm redeemVoucherForm, final BindingResult bindingResult, final RedirectAttributes redirectModel, final Model model, HttpServletRequest request) {
LOG.debug("<POST> Redeeming voucher...");
return REDIRECT_PAGE_URL;
}
pageDisplay.jsp:
<c:url value="/page/redeem-voucher" var="redeemVoucherAction" />
<form:form action="${redeemVoucherAction}" method="post" commandName="redeemVoucherForm">
<form:input cssClass="form-control" type="text" path="redeemVoucherForm.voucherCode"/>
<button type="submit" class="btn btn-primary btn-block checkoutButton">
<spring:theme text="Redeem Voucher"/>
</button>
</form:form>
What else could I be missing, when I have set model redeemVoucherForm?
I believe this line
<form:input cssClass="form-control" type="text" path="redeemVoucherForm.voucherCode"/>
should be
<form:input cssClass="form-control" type="text" path="voucherCode"/>
The path element of a <form:input> should be relative to the object you've set as the commandName of your <form:form>. In your case, this object is an instance of your class RedeemVoucherForm.
If you set the path to redeemVoucherForm.voucherCode, Spring looks for a redeemVoucherForm property on your class RedeemVoucherForm. It expects the value of this to be some object with a voucherCode property, from which it can read the form value. Of course, the redeemVoucherForm property doesn't exist, hence you get the error.

java.lang.IllegalStateException: Neither BindingResult nor plain target object available as request attribute

When I am trying to submit (Spring) form query:
I don't get the message.
Controller
#RequestMapping(value = "beerbean", method = RequestMethod.GET)
public String showForm(#ModelAttribute("beerbean") BeerBean beerbean){
return "addbeerform";
}
#RequestMapping(value = "beerbean", method = RequestMethod.POST)
public String newBeer(Model model, #Valid #ModelAttribute BeerBean beerbean,
BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "addbeerform";
}
model.addAttribute("beani", beerbean);
return "showBeer";
}
addbeerform.jsp
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<form:form commandName="beerbean" action="${pageContext.request.contextPath}/app
/beerbean" method="POST">
<form:input path="name" /><form:errors path="name" /><br/>
<form:input path="id" /><form:errors path="id" /><br/>
<input type="submit">
</form:form>
When there isn't errors in fields it works and goes to "showBeer", but when there is it just crashes. I have also BeerBean class which implements Serializable etc., but don't think the solution is there (variables there are written like parameters in form, input path="name" goes to private String name etc).
I suggest to explicitly specify name of model attribute:
public String newBeer(
Model model,
#Valid #ModelAttribute("beerbean") BeerBean beerbean,
BindingResult bindingResult
) {

spring 3 auto form field validation with file upload

I was using JSR 303 validation with hibernate validator to have fields validated automatically by specifying #Valid on the controller method. Validation was working fine. I have know added an upload field to the form and have added a #RequestParam("file") as a MultipartFile file. Now it works only if all fields are valid on submission otherwise I get a 404 (Bad Request). If I remove the #Valid annotation I get the javax.validation.ConstraintViolationException with all the validation violations with Status 500.
I'm using Spring 3.2
my form:
<form action="#springUrl("/admin/stores/save")" method="POST" enctype="multipart/form-data">
Name:
#springBind( "store.name" )
<input type="text"
name="${status.expression}"
value="$!status.value" /><br>
......
<input type="file" name="file" accept="image/*">
<input type="submit" value="submit"/>
</form>
Controller:
#RequestMapping(value="/save", method = RequestMethod.POST)
#Transactional
public String save(#Valid #ModelAttribute Store store, #RequestParam("file") MultipartFile file, BindingResult bindingResult, ModelMap model) {
if (bindingResult.hasErrors()) {
model.addAttribute("message", "Failed");
model.addAttribute("store", store);
return "admin/stores/form";
} else {
.....
your problem is in method argument order. #ModelAttribute must be followed by BindingResult argument. Look at Spring documentation and check also Example 17.1. Invalid ordering of BindingResult and #ModelAttribute.
. You also should add MultipartFile to form class (Store) if it is part of it.
Store {
/* Your other fields */
#NotNull
private MultipartFile file;
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file= file;
}
}

Writing to a Spring-bound Map in Velocity

I'm trying to iterate over a Map in Velocity using Spring MVC and creating a FORM from it. This works fine, but I can't get the values to save back to the map.
Here's the template:
<form method="POST" action="save">
#foreach($item in $data.data.entrySet())
$item.key
<input name="data.data['$item.key']" value="$data.data[$item.key]" />
<br />
#end
<input type="submit" value="submit">
</form>
and the backing bean looks like this:
#Controller
#RequestMapping("/")
public class HomeController {
#RequestMapping("/")
public String home(Model model) {
DataBean data = new DataBean();
data.addItem("name", "name123");
data.addItem("firstname", "firstname345");
model.addAttribute("data", data);
return "home";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(#Validated DataBean data) {
System.out.println(data.getData());
return "home";
}
}
Displaying the form looks fine, but the map is always empty on submit.
Any ideas? Thanks!

Categories