how to get form values to controller in spring mvc - spring

I am trying to get form values from jsp to controller in spring mvc, but i am not able to get form data.
This is my DTO (bean)
public class LoginDTO implements Serializable {
private Long id;
private String username;
private String password;
// setter and getter methods
}
and my Jsp
<form class="form-signin" action="test" method="get" modelAttribute="userFormData">
<input type="text" class="form-control"
placeholder="Email" required autofocus>
<input type="password" class="form-control"
placeholder="Password" required>
<input class="btn btn-md btn-success btn-block"
type="submit" value="Signin">
</form>
and my controller
#RequestMapping(value = "/test", method = RequestMethod.GET)
public String checkLogin(#ModelAttribute("userFormData") LoginDTO formData, BindingResult
result) {
System.out.println("Controller...");
System.out.println("=====> " + formData.getUsername());
System.out.println("=====> " + formData.getPassword());
}

Add names to the controls on your JSP pages.
<input type="text" name="username" ...>
<input type="password" name="password" ...>
To let spring understand which form control value should go to which property of the LoginDTO

we can also use the springframework has given us a form tags.so that we can also use that but in that case you have to define your the input path same as the member varibale given in your class.
like this
<form:form method="post" modelAttribute="userFormData">
<form:input path="username" />
<form:input path="password" />
Then in the controller you can write like this as you have written
public String checkLogin(#ModelAttribute("userFormData") LoginDTO formData, BindingResult
result)

In case you want to get the result on other jsp page as well as on console then do:
public String checkLogin(#ModelAttribute("userFormData") LoginDTO formData, BindingResult
result , Model model){
System.out.println("=====> " + formData.getUsername()); //this outputs username on console
System.out.println("=====> " + formData.getPassword()); //this outputs password on console
model.addAttribute("LoginDTO ", LoginDTO );
return "success"; //this is the return page where the username and password will be rendered as view
}

Related

Request method 'POST' not supported in spring MVC web app

i am using .html in mvc app. it's showing app perfectly.inside login.html i have used form with method POST for submission but when i submit form showing error that POST is not supported.but when i change everything with .jsp then it let submit form.
here's the controller
#Controller
public class mainController {
#RequestMapping("/login")
public ModelAndView login(Locale locale , Model m) {
System.out.println("modal");
return new ModelAndView ("login");
}
#RequestMapping(path = "/user" , method=RequestMethod.POST)
public String user(#ModelAttribute("user") User user) {
System.out.println(user);
return "user";
}
}
this is login form
<form action="user" method="post" name="user">
<input type="text" name="username" placeholder="uname"/> <br>
<input type="password" name="password" placeholder="password"/> <br>
<input type="date" name="date" placeholder="date"/> <br>
<button type="submit">Submit</button>
</form>
what can I do to submit form using POST method from .html file.

How to pass model value in thymeleaf input text

I have data in a Model object and I want to put that into the input field in my Thymeleaf template, such that if the value is null, nothing will be displayed and otherwise, the input will have the value inside it. I tried this but this is not working.
<input id="first_name" type="text" name="firstName" placeholder="First" value=${accountInfo.firstName} maxlength=31 required>
I passed the values into the model object inside the java exception handler like so:
#ExceptionHandler(value=SignupFormException.class)
public String handle(HttpSession session, SignupFormException ex, Model response) {
response.addAttribute("accountInfo", (Account) session.getAttribute("accountToRegister"));
response.addAttribute("Error", ex.getMessage());
session.invalidate();
return "redirect:/signup";
}
How to fetch the attributes from the accountInfo object I passed in my model in my thymeleaf template?
Update:
Now it is working but not the first time the page is accessed when there is no model object. Following is the code:
My thymeleaf form:
<form action="/signup_do" th:object="${accountInfo}" method="post">
<input id="first_name" type="text" name="firstName" placeholder="First" th:value=*{firstName} maxlength=31 required>
Controller:
#PostMapping("/signup_do")
public String register(Account account, HttpSession session) {
session.setAttribute("accountToRegister", account);
accountManagement.accountRegistration(account);
return "Success";
}
There is a account registration service that throws SignupFormException which is handled by:
#ExceptionHandler(value=SignupFormException.class)
public String handle(HttpSession session, SignupFormException ex, Model response) {
response.addAttribute("accountInfo", (Account) session.getAttribute("accountToRegister"));
response.addAttribute("Error", ex.getMessage());
session.invalidate();
return "redirect:/signup";
}
And only now do I have a model object with properties for the thymeleaf template...
change "value" to "th:field"
OR
change "value" to th:value="${accountInfo.firstName}"
<form action="#" th:action="#{/yourURL}" th:object="${accountInfo}" method="post">
<input id="first_name" type="text" name="firstName" placeholder="First" th:field=*{firstName} maxlength=31 required>
<input type="submit" class="btn btn-primary" value="Submit">
</form>

Insert jsp form to database using spring boot

I'm a beginner in spring boot I start with creating a contact form that send data to data base. this is the form:
<form:form method="POST" id="contactform" modelAttribute="message">
<div class="form">
<div class="six columns noleftmargin">
<label name="name">Name</label>
<form:input path="name" type="text" class="smoothborder" placeholder="Your name *"/>
</div>
<div class="six columns">
<label name="email">E-mail address</label>
<form:input path="email" type="text" class="smoothborder" placeholder="Your e-mail address *"/>
</div>
<label name="comment">Message</label>
<form:textarea path="comment" class="smoothborder ctextarea" rows="14" placeholder="Message, feedback, comments *"></form:textarea>
<input type="submit" id="submit" class="readmore" value="Submit"/>
</div>
</form:form>
And this is my conact controller:
#Autowired
private MessageRepository messageRepository ;
#RequestMapping(value= "/newmessage", method = RequestMethod.GET)
public String newMessage(ModelMap model) {
Message message = new Message();
model.addAttribute("message", message);
return ("/contact");
}
#RequestMapping(value="/newmessage",method=RequestMethod.POST)
public String saveMessage( Message message, BindingResult result, ModelMap model)
{
if (result.hasErrors()) {
return "/contact";
}
messageRepository.save(message);
model.addAttribute("success", "Message " + message.getName() + " "+ message.getEmail() + " "+ message.getComment()+ " registered successfully");
//return "success";
return "/homepage";
Folder Structure
You need to set the action of the form. If you want to hit /newmessage while submitting form, then you need to change as following :
<form:form method="POST" id="contactform" action="/newmessage" modelAttribute="message">
<!-- The elements of the form -->
</form:form>
Also, you need to add the modelAttribute to your controller method. And you should return only the name of the jsp page. If your page name is homepage.jsp then you should only return homepage from your controller method. Of course, homepage.jsp file needs to be in WEB-INF folder.
#RequestMapping(value="/newmessage",method=RequestMethod.POST)
public String saveMessage(#ModelAttribute("message") Message message, BindingResult result, ModelMap model) {
// Rest of the code
return "homepage";
}

how to pass parameter from HTML with Thymeleaf to Spring Controller?

I have a controller in Spring Boot that needs to recieve a parameter and an object by POST. The parameter is NOT an object or part of if.
Here is the Thymeleaf form without the parameter. It works fine in a stand-alone page, but the same code does not work when I use it in a page that shows an article:
<form th:action="#{/addcomment}" th:object="${comment}" method="post">
<input type="text" th:field="*{commenttext}" />
<button type="submit">send</button>
</form>
because when I add the
<input type="hidden" th:field="*{id}" th:with="id=1" value="${id}"/>
or
<input type="hidden" th:field="*{id}"/>
or
<input type="hidden" th:field="*{id}" value="1"/>
my Controller prints 0 in the console, when the value should be 1... (and even if I change it to value="true".... this comes from the Chrome console:
<input type="hidden" class="sr-only" value="0" id="id" name="id" />
no matter what I use
#RequestMapping(value = "/addcomment", method = RequestMethod.POST)
ModelAndView addStatus(ModelAndView modelAndView, #Valid Comment comment, #RequestParam("id") Long id, BindingResult result) {
Comment commentform = new Comment();
Announcement announcement = announcementService.readAnnouncement(id);
String sanatizedcommenttext = htmlPolicy.sanitize(comment.getCommenttext());
commentform.setCommenttext(sanatizedcommenttext);
commentform.setDate(new Date());
commentform.setAnnoucements(announcement);
modelAndView.setViewName("addcomment");
if (!result.hasErrors()) {
commentService.createComment(commentform);
modelAndView.getModel().put("comment2th", new Comment());
modelAndView.setViewName("redirect:/addcomment");
}
return modelAndView;
}
By the way, the parameter is in the url (but I would like to know how to send it to the controller independently of where it is located).
thanks for your help!
You only have to add this changes
<input type="hidden" name="paramName" value="1"/>
In your Controller
#RequestMapping(value = "/addcomment", method = RequestMethod.POST)
ModelAndView addStatus(ModelAndView modelAndView, #Valid Comment comment, #RequestParam("paramName") Long id, BindingResult result) {
The problem was, that you were using the thymeleaf tags for input fields, then Spring thinks the attribute id its inside the object Comment, but it's not your case, so you have to use normal input tag.

Spring MVC validation errors are not displayed in Freemarker template

I'm trying to display validation errors in a 'user registration' page built with freemarker template if a controller returns binding errors.
My controller's code is as follows:
#Controller
#RequestMapping("/")
public class UserController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/registration", method = RequestMethod.GET)
public String registration(Model model) {
model.addAttribute("userForm", new User());
return "registration";
}
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute("useraccount") User userForm, BindingResult bindingResult, Model model) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.save(userForm);
securityService.autologin(userForm.getUsername(), userForm.getPasswordConfirm());
return "redirect:/explore";
}
while this is the registration.ftl freemarker template I am trying to build :
<div>
<fieldset>
<h1>Create your Account</h1>
<form id="regForm" class="idealform" action="registration" method="post" name='useraccount'>
Username: <input type="text" name="username" /> <errors path="username" cssClass="error"/><br/>
Password: <input type="text" name="password" /><errors path="password" cssClass="error"/><br/>
<label class="main-label" style="width: 91px;"> </label>
<input type="submit" value="submit">
</form>
</fieldset>
I tried also the solution recommended here:
Displaying Spring MVC validation errors in Freemarker templates
and the registration.ftl becomes:
<#assign form=JspTaglibs["http://www.springframework.org/tags/form"] />
<#macro formErrors>
<#assign formErrors><#form.errors path="*" /></#assign>
<#if formErrors?has_content>
<div id="errors">
<#spring.message "admin.error.globalMessage" />
</div>
</#if>
</#macro>
<div>
<fieldset>
<h1>Create your Account</h1>
<#form.form id="regForm" class="idealform" action="registration" method="post" name='useraccount'>
Username: <input type="text" name="username" path="username" /> <br/>
Password: <input type="text" name="password" path="password" /><br/>
<#formErrors />
<label class="main-label" style="width: 91px;"> </label>
<input type="submit" value="submit">
</#form.form>
</fieldset>
</div>
but still the validation messages are not displayed.
Could you share your thoughts with me on this issue?
Thank you very much.
I rewrote your controller code to something like this:
#Controller
#RequestMapping("/")
public class UserController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/registration", method = RequestMethod.GET)
public String registration(#ModelAttribute(name = "userForm") User user) {
return "registration";
}
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute(name = "userForm") User user, BindingResult result) {
userValidator.validate(user, result);
if (result.hasErrors()) {
return "registration";
}
userService.save(user);
securityService.autologin(user.getUsername(), user.getPasswordConfirm());
return "redirect:/explore";
}
}
1) There is no need to use model.addAttribute("modelName", model) if you use a constructor without arguments, instead you can use a #ModelAttribute annotation specifying the name attribute (by default the name goes from the class name). You only have to be sure that this model is in a consistent state. Also you need to pass the name exactly the same as you use in your view (freemarker template).
Now "registration.ftl"
...
<#import "/spring.ftl" as spring/>
...
<fieldset>
<h1>Create your Account</h1>
<form id="regForm" class="idealform" action="<#spring.url '/registration'/>" method="post">
<#spring.bind 'userForm.username'/>
Username: <input type="text" name="${spring.status.expression}" value="${spring.status.value?html}"/>
<#list spring.status.errorMessages as error>
<span class="error">${error}</span>
<br>
</#list>
<#spring.bind 'userForm.password'/>
Password: <input type="password" name="${spring.status.expression}" value="${spring.status.value?html}"/>
<#list spring.status.errorMessages as error>
<span class="error">${error}</span>
<br>
</#list>
<label class="main-label" style="width: 91px;"> </label>
<input type="submit" value="submit">
</form>
</fieldset>
...
1)You need <#import "/spring.ftl" as spring/> in order to add spring's user-defined directives that are pretty useful.
2)Use <#spring.bind 'userForm.username'> directive to bind following input to your model. Here "userForm" is your model and "username" is a field that you want to bind. This directive also declares new variable "spring.status" that contains an "expression" variable - for a path, a "value" - to populate the form in case it's returned with errors, and "errorMessages" from BindingResult.
3)If you use a message source to support different languages you should change <span class="error">${error}</span> to something like <#spring.message '${error}'/> otherwise you'll get just message codes.
Hope it helps.

Resources