Spring MVC: #RequestParam validation - validation

In my register form i'm using Bean Validator (JSR-303) for validate User object, and need to validate separately password confirmation, because it is not a member of User. I have a problem to assign error message for confirm field. How to do that ?
View:
<form:form modelAttribute="user" method="post" action="register.html">
<div class="fcell">
<div class="clabel"><spring:message code="label.password"/></div>
<div class="cdata"><form:password path="password"/></div>
<div class="cmsgs"><form:errors path="password" /></div>
</div>
<div class="fcell">
<div class="clabel"><spring:message code="label.confirm"/></div>
<div class="cdata"><input type="password" name="confirm"/></div>
<div class="cmsgs"></div>
</div>
</form:form>
Controller:
#RequestMapping("/register.html")
public String register(#RequestParam("confirm") String confirm, #ModelAttribute("user") #Valid User user, BindingResult result) {
if(!DigestUtils.sha256Hex(confirm).equals(user.getPassword())) {
/* Invalid property 'confirm' ... */
result.rejectValue("confirm", "text.passwords_not_equal");
}
return "register";
}

In this case confirmation can be considered a part of model object, like this:
public class RegistrationForm {
#Valid
private User user;
private String confirm;
...
}
...
public String register(#ModelAttribute("user") #Valid RegistrationForm user,
BindingResult result) { ... }
...
<div class="cdata">
<form:password path="confirm"/></div>
<div class="cmsgs"><form:errors path="confirm" />
</div>
...

Related

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";
}

Spring Boot ModelAndView - cannot update value to Model

I am trying to create a form with 3 fields within the class LoginForm: usuario, senha, msgLogin.
I receive the fields usuário and senha from the input boxes and then I try to redirect to the same page with the same fields plus the field MsgLogin. But I've not been able to update the msgLogin field and I don't understand why.
These are the code:
HTML:
<form id="frmLogin" class="form col-md-12" action="#" th:action="#{/login}" th:object="${loginForm}" method="post">
<div class="form-group">
<label for="usuario" class="col-md-1">Usuário: </label>
<input type="text" id="usuario" placeholder="Email" th:field="*{usuario}"/>
</div>
<div class="form-group">
<label for="senha" class="col-md-1">Senha: </label>
<input type="password" id="senha" placeholder="senha" th:field="*{senha}"/>
</div>
<div class="row">
<button id="entrar">Entrar</button>
</div>
<div class="row">
<div id="msgLogin"></div>
<p th:text="${loginForm.msgLogin}" />
</div>
</form>
The Controller:
#RequestMapping("/")
public String init(#ModelAttribute LoginForm loginForm) {
Logger.getAnonymousLogger().info("Tela Inicial.");
return "home";
}
#PostMapping("/login")
public ModelAndView entrar(LoginForm loginForm) throws IOException {
Logger.getAnonymousLogger().info("Entrando no Internet Banking.");
service.login(usuario, senha);
ModelMap model = new ModelMap();
loginForm.setMsgLogin("I want to update that value!");
model.addAttribute("loginForm", loginForm);
return new ModelAndView("redirect:/", model);
}
Class using Lombok:
#Getter
#Setter
public class LoginForm {
private String usuario;
private String senha;
private String msgLogin;
}
A redirect send a 302 HTTP status back to the browser to resubmit using a new url, so it resubmits the same two fields to the new url. There's no expectation of payload data in the 302 response.
In your Controller, change the last line in your entrar method to: return new ModelAndView("/login", model);

how to pass checkbox value from jsp to java class

I have in my jsp page some checkbox and I want to pass in my spring controller the checked ones.
insertTaskInformation.jsp
<body>
<div align="center">
<strong> <strong>Title:</strong>${task.title} <form:form
action="addSymbol" method="post" name="catch">
<c:forEach var="symbol" items="${symbols}">
<input type="checkbox" name="id" value="${symbol.type} }">${symbol.type}<BR>
</c:forEach>
<input type="submit" value="Submit">
</form:form>
</strong>
</div>
</body>
taksController.java
#RequestMapping(value="/addSymbol", method = RequestMethod.POST)
public String addSymbol() {
return "administration/taskRecap";
}
You can use spspring:form library and you add in your controller something like this :
#PostMapping("/greeting")
public String greetingSubmit(#ModelAttribute Greeting greeting) {
return "result";
}
And In your first controller, you add an attribute to the model with model.addAttribute(new greeting() ) so the full code will be
#RequestMapping(value="/addSymbol", method = RequestMethod.POST)
public String addSymbol(Model model) {
model.addAttribute(new greeting() )
return "administration/taskRecap";
}
For more information check here

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.

Can not get the error message in the spring form

I am woring on an Spring Web application with the CURD operation for the Entity Department, this is the handler for processing the submit of a new Department:
#RequestMapping(value = "/", method = RequestMethod.POST)
public String addSubmit(#Valid Department department, BindingResult result,SessionStatus status) {
if (result.hasErrors()) {
return "department/add";
} else {
departmentService.save(department);
status.setComplete();
return "redirect:/departments/" + department.getId();
}
}
Model:
#Entity
public class Department extends BaseNamedEntity {
#NotNull
#NotEmpty
private String description;
...
}
And the form:
<form:form method="post" action="${fmURL}" class="form-horizontal" commandName="department">
<form:hidden path="id"/>
<spring:bind path="name">
<div class="control-group ${status.error ? 'error' : ''}">
<label class="control-label">Name</label>
<div class="controls">
<form:input path="name"/>
<span class="help-inline">${status.errorMessage}</span>
</div>
</div>
</spring:bind>
<form:form>
However, once I submit the form with empty field, normally, the errorMessage should be displayed and the related div should be add a class with error, however I can not found the error message.
What's going on?
BTW, the example is derive from Spring-petclinic project.

Resources