I want to create a website that displays a form. The fields of the form depend on a request parameter (and also the form backing bean). This is my controller that renders the different forms:
@Controller
public class TestController {
@Autowired
private MyBeanRegistry registry;
@RequestMapping("/add/{name}")
public String showForm(@PathVariable String name, Model model) {
model.addAttribute("name", name);
model.addAttribute("bean", registry.lookup(name));
return "add";
}
}
The corresponding view looks like this:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<form method="post" th:action="@{|/add/${name}|}" th:object="${bean}">
<th:block th:replace="|${name}::fields|"></th:block>
<button type="submit">Submit</button>
</form>
</body>
</html>
Following is an example fragment that displays the form fields:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<th:block th:fragment="fields">
<label for="firstName">First name</label><br />
<input type="text" id="firstName" th:field="*{firstName}" /><br />
<label for="lastName">Last name</label><br />
<input type="text" id="lastName" th:field="*{lastName}" />
</th:block>
</body>
</html>
The looked up bean would be like this:
public class MyExampleBean {
private String firstName;
private String lastName;
// Getters & setters
}
The form is rendered correctly, but how can I receive the form back in the controller? And how can I validate the submitted bean? I tried the following method, but obviously it can not work:
@RequestMapping(value = "/add/{name}", method = RequestMethod.POST)
public String processForm(@PathVariable String name, @Valid Object bean) {
System.out.println(bean);
return "redirect:/add/" + name;
}
Spring creates a new instance of Object
but the submitted values are lost.
So how can I accomplish this task?
When such a request arrives, the container picks a Thread from the pool and, within that Thread, executes the service() method on the DispatcherServlet which dispatches to the correct @Controller instance that Spring registered for you (from your configuration). So YES, Spring MVC classes must be thread safe.
The @Controller annotation indicates that a particular class serves the role of a controller. Spring Controller annotation is typically used in combination with annotated handler methods based on the @RequestMapping annotation. It can be applied to classes only. It's used to mark a class as a web request handler.
In Spring MVC, controller methods are the final destination point that a web request can reach. After being invoked, the controller method starts to process the web request by interacting with the service layer to complete the work that needs to be done.
Creating the controller class web package in the src/main/java source folder and selecting New → Class. (If Class is not offered on the New menu, then the Java perspective may not be being used. Look for the Class option under Other… in the Java section.) Name the new class GreenPagesController and press Finish.
If you only wanted to deal with a limited number of beans, you could have one @RequestMapping
method for each bean, all delegating to a private method that would do the job. You can find an example here.
If you want to be able to accept bean dynamically, you will have to do by hand what Spring does automagically :
PathVariable
nameBut hopefully Spring offers the subclasses of WebDataBinder
as helpers :
@RequestMapping(value = "/add/{name}", method = RequestMethod.POST)
public String processForm(@PathVariable String name, WebRequest request) {
//System.out.println(bean);
Object myBean = registry.lookup(name);
WebRequestDataBinder binder = new WebRequestDataBinder(myBean);
// optionnaly configure the binder
...
// trigger actual binding of request parameters
binder.bind(request);
// optionally validate
binder.validate();
// process binding results
BindingResult result = binder.getBindingResult();
...
return "redirect:/add/" + name;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With