Writing to a Spring-bound Map in Velocity - java

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!

Related

When using Spring, When is the Form class property stored in the value that's sent from the html form tag?

I should implement like execute(#ModelAttribute RegisterForm registerForm, Model model) in Controller class below.
I forgot put the #ModelAttribute.
However it works. When is name in RegisterForm class stored in the value that's sent from html?
Part of Controller class
#Controller
public class RegisterController {
#RequestMapping(value = "/register/")
public String register() {
return "register";
}
#RequestMapping(value="/register/execute", method=RequestMethod.POST)
//(#ModelAttribute RegisterForm registerForm, Model model) is better
public String execute(RegisterForm registerForm, Model model) {
model.addAttribute("registered_name", registerForm.getName());
return "index";
}
}
Form class
public class RegisterForm {
private String name; //when is this property stored in the value??
public String getName() {
return name;
}
}
Part of HTML file
<div class="input">
<p>Enter your name</p>
<input type="text" name="name" />
</div>
Please let me know if you need more information to solve this.Thanks.
add setter name to your class RegisterForm it's important
you should lik this :
<form action="register/execute">
<div class="input">
<p>Enter your name</p>
<input type="text" name="name" />
</div>
<form>
or usign tag form spring :
add this in your controller
#RequestMapping(value="/index", method=RequestMethod.POST)
public String executet(Model model) {
model.addAttribute("registerForm ", new RegisterForm ());
return "index";
}
include this code in your jsp
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<form:form method="POST" modelAttribute="registerForm ">
<form:input path="name" />
<input type="submit" value="Register">
</form:form>

Spring controller get empty object

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.

Howto send vars and receive model in same time from same controller?

In Spring boot who receive post model and in same time send vars to thymeleaf template?
#Controller
public class ProfilingController {
#GetMapping("/")
public String main(Model model){
FormModel form_model = new FormModel();
model.addAttribute("form_model", form_model);
model.addAttribute("demo", "abc");
return "main_template";
}
#PostMapping("/")
public String receive(#ModelAttribute ModelForm form_model){
FormModel form_model = new FormModel();
// How to set model to send the var to thymeleaf template?
model.addAttribute("form_model", form_model);
model.addAttribute("demo", "abc");
return "main_template";
}
}
If in post method receibe the model, how set the model to send vars to template?, if send two params does not works:
#PostMapping("/")
public String receive(Model model, #ModelAttribute ModelForm form_model){
The model_form is empty.
The template:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
</head>
<body>
<form class="form-signin" action="#" method="post" th:action="#{/}" th:object="${form_model}">
<input th:field="*{email}" required="required" type="email" />
<input th:field="*{password}" type="password" />
<p th:text="${demo}"></p>
<button type="submit">Submit</button>
</form>
</body>
</html>
You can do this with ModelMap as below:
I have commented new form_model object creation assuming that you need to keep the received data to send back to the user.
#PostMapping("/")
public String receive(#ModelAttribute ModelForm form_model, ModelMap modelMap){
//other code to call service layer & save the data
//Commented new object creation for FormModel
//FormModel form_model = new FormModel();
modelMap.addAttribute("form_model", form_model);
modelMap.addAttribute("demo", "abc");
return "main_template";
}

Neither BindingResult nor plain target object for bean name when running application

index.jsp
<f:form action="emp_change.htm" method="POST" commandName="index">
<div id="login_box">
<div id="form_val">
<div class="label">Username:</div>
<div class="control"><f:input path="emailId" /></div>
<div style="clear:both;height:0px;"></div>
<div class="label">Password:</div>
<div class="control"><f:input path="password" type="password" /></div>
<div style="clear:both;height:0px;"></div>
<div id="msgbox"></div>
<div id="login_foot">
<input type="submit" name="action" id="login" value="Login" class="send_button" />
</div>
</div>
</div>
</f:form>
AdminInfoControl.java
#Controller
public class AdminInfoControl {
private AdminInfoService service;
#RequestMapping(value = "/emp_change", method = RequestMethod.POST)
public String doActions(#ModelAttribute JtAdminInfo emp, BindingResult result, #RequestParam String action, Map<String, Object> map) {
service = new AdminInfoService();
JtAdminInfo empResult = new JtAdminInfo();
switch (action.toLowerCase()) {
case "login":
JtAdminInfo search = service.getFindAdmin(emp.getEmailId());
empResult = search != null ? search : new JtAdminInfo();
break;
}
map.put("index", empResult);
map.put("empList", service.getAll());
return "index";
}
}
I'm getting following error :
Neither BindingResult nor plain target object for bean name 'emp_change' available as request attribute
Anyone please help me to correct this. Please let me know, if information is not sufficient.
Just answered on almost the same question.. You are obtaining emp_change as a model attribute in doActions method but you didn't set it as a model attribute previously. So, set your emp_change as a model attribute in some method that e.g. shows your index.jsp page. Something like this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showIndex() {
ModelAndView mav = new ModelAndView("index");
mav.addObject("emp_change", new JtAdminInfo ());
return mav;
}
I have added following method in my controller and works fine.
#RequestMapping("/index")
public String setupForm(Map<String, Object> map) {
map.put("index", new JtAdminInfo());
return "index";
}

Edit form validation with Spring MVC

I use Spring MVC and Spring form validation in my project.
There is class named Group in object model and I created form for editing it.
Form
<spring:url var="saveGroup" value="/teacher/groups/save"/>
<form:form action="${saveGroup}" method="post" modelAttribute="group">
<form:hidden path="id"/>
<div id="nameDiv" class="control-group">
<form:label path="title">Title:</form:label>
<form:input path="title"/>
<form:errors path="title"/>
</div>
<div id="specDiv" class="control-group">
<form:label path="title">Specialty:</form:label>
<form:select path="specialty">
<form:options items="${specialties}" itemValue="id" itemLabel="title"/>
</form:select>
</div>
<div class="center">
<spring:url var="groups" value="/teacher/groups"/>
<input class="btn btn-primary" type="submit" value="Save"/>
<a class="btn" href="${groups}"> Cancel </a>
</div>
</form:form>
Controller
#Controller
#RequestMapping("/teacher/groups")
public class GroupsController {
#Autowired
private GroupService groupService;
#Autowired
private SpecialtyService specialtyService;
#ModelAttribute("group")
public Group setGroup(Long id) {
if (id != null) {
return groupService.read(id);
} else {
return new Group();
}
}
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Specialty.class, "specialty",
new SpecialtyEditor(specialtyService));
binder.setValidator(new GroupValidator());
}
#RequestMapping("")
public ModelAndView groups() {
return new ModelAndView("teacher/groups/list", "groups",
groupService.list());
}
#RequestMapping("/edit")
public ModelAndView editGroup() {
return new ModelAndView("teacher/groups/edit", "specialties",
specialtyService.list());
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveGroup(#Valid Group group, BindingResult result) {
if (result.hasErrors()) {
return "forward:/teacher/groups/edit";
}
groupService.update(group);
return "redirect:/teacher/groups";
}
}
I want to set the adequate behavior of my form in the case of failed validation. I.e. it should save its state but only show validation error message (as when using javascript to validate).
I thought that "forward:/teacher/groups/edit" will again forward request to editGroup() with saved objects group and result. But when I failed validation form just reloads and show start state of edited group: no errors and no saved changes.
How can I do that correctly?
Thanks!
I solved problem by not forwarding request to other method but sending answer to user immediately. Now it works and looks like:
#RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView saveGroup(#Valid Group group, BindingResult result) {
if (result.hasErrors()) {
return new ModelAndView("/teacher/groups/edit", "specialties", specialtyService.list());
}
groupService.update(group);
return new ModelAndView("redirect:/teacher/groups");
}

Categories