I am able to validate form and display Spring validation error with Spring form tag. Instead of displaying as HTML markup how can I display those errors using jQuery Noty Plugin?
Controller:
#RequestMapping(value = "/Register", method = RequestMethod.POST)
public ModelAndView Registeruser(#ModelAttribute("registerBean") #Valid RegisterBean registerBean, BindingResult bindingResult) {
ModelAndView mv = new ModelAndView();
if (bindingResult.hasErrors()) {
mv.setViewName("index");
mv.addObject(registerBean);
} else {
boolean registered = userservice.RegisterUser(registerBean);
if (registered) {
List<SimpleGrantedAuthority> authList = new ArrayList<SimpleGrantedAuthority>(1);
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(registerBean.getEmail(), registerBean.getPassword(), authList);
SecurityContextHolder.getContext().setAuthentication(auth);
mv.setViewName("auth/Home");
} else {
mv.setViewName("index");
}
}
return mv;
}
You didn't mention which view technology you are using. I assume that JSP is in use.
First you should render any error message into a separate hidden container.
In this example product is my modelAttribute. It is completely up to you what you are showing to your users in case of an error. In this example a unordered list of validation type on property and validation message will be shown.
<%# taglib prefix="s" uri="http://www.springframework.org/tags"%>
<s:hasBindErrors name="product">
<div id="error-noty" style="display:none;">
<h3>You have errors in your input!</h3>
<ul>
<c:forEach items="${errors.fieldErrors}" var="error">
<li>${error.codes[1]} ${error.defaultMessage}</li>
</c:forEach>
</ul>
</div>
</s:hasBindErrors>
Then you should initialize noty only if a container with the selector #error-noty could be found in the page.
Hand over the html from the hidden container to noty and you're done.
<script>
var errors = $('#error-noty');
if(errors.html()) {
noty({text: errors.html()});
}
</script>
A working example can be found here.
Related
I am very much new to thymeleaf and i have been working on project that works great in jsp.Now where i have to move to spring boot i am facing some problems. i have this controller i want when user requestmapped /staff and userClickManager got the value true and i want to change the contents in same file that is index.html
#RequestMapping(value = "/", method = RequestMethod.GET)
private ModelAndView index() {
ModelAndView model = new ModelAndView("index");
model.addObject("title", "Home");
model.addObject("userClickHome", true);
return model;
}
#RequestMapping("/staff")
private static ModelAndView staff(){
ModelAndView view = new ModelAndView("index");
view.addObject("title", "Manager");
view.addObject("userClickManagers", true);
return view;
}
here is the proto of my old jsp code just want them in thymeleaf thanks.
<c:if test="${userClickHome==true}">
<!-- load the manager.jsp file -->
<%#include file="homeContent.jsp" %>>
</c:if>
<c:if test="${userClickManagers==true}">
<!-- load the manager.jsp file -->
<%#include file="Manager.jsp" %>
</c:if>
What does your thymeleaf html look like? If you read set attribute use th:insert or th:replace in your condition.
I had a working form submit on a jsp that takes some basic info as strings. The controller validates the user inputs and determines if it should go back to the page to display error msg or go to a new page. Then I modified the form submit to allow users to upload files. The problem is when I return the String in my controller method, it doesn't go to the right jsp pages anymore. It just goes to a blank page with text of "/ad/adAdd3/12345" or "redirect:/ad/adDetail/12345". What am i missing?
jsp:
<form:form modelAttribute="ad" method="post" class="form-horizontal" autocomplete="off" id="add-ad-form"
action="?${_csrf.parameterName}=${_csrf.token}" enctype="multipart/form-data">
controller:
#RequestMapping(value = "/ad/adAdd3/{categoryId}", method = RequestMethod.POST)
public #ResponseBody String postAdAdd(#RequestParam("categoryId") int categoryID,
#ModelAttribute("ad") #Valid Ad ad,
BindingResult aaResult,
SessionStatus aaStatus, Principal aaPrincipal) {
if (aaResult.hasErrors()) {
return "/ad/adAdd3/" + categoryID;
} else {
ad = this.caService.saveAd(ad, categoryID,
((UserDetailsImpl) ((Authentication) aaPrincipal)
.getPrincipal()).getUser());
aaStatus.setComplete();
return "redirect:/ad/adDetail/" + ad.getId();
}
}
#ResponseBody is the problem. Once I removed it, everything is working now.
When I use <form:input path="name" /> inside my jsp page it show HTTP Status 500 Error.
The issue that I'm facing is because of this tag <form:input path="name"> But If I remove this tag and use normal input tag it's working fine for me.
Any Help will be Appreciated.
I Also Include Taglib for form
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
My Jsp file is
Code Inside My controller is
and The Error it's displaying to me is
Use ModelAndView like below and create a bean with setters and getters of property "name".
#RequestMapping(value = "/insert", method = RequestMethod.GET)
public ModelAndView insert() {
return new ModelAndView("script", "command" , new MyBean());
}
#RequestMapping(value = "/insert", method = RequestMethod.POST)
public ModelAndView attackHandler(#ModelAttribute("myBean")MyBean mybean) {
System.out.println(mybean.getName());
return new ModelAndView("script", "command" , mybean);
}
Please provide the Bean(with setter and getter) for you input value and Include your bean in servlet method insert and attackHandller .
like
public ModelAndView attackHandller(#ModelAttribute("beanData") #Validated BeanData beanData, BindingResult bindingResult,Model model){}
I m actually studying the Spring framework with Spring Boot and Sprint MVC.
I m doing a form that post some data to complete an object, and I need to validate some values.
The fact is that the validation works, in fact, if I dont respect the validation, I m "redirected" (not really in fact, the URL doesn't change) to the error.html content.
How should I do to manage my redirection correctly ? This doesn't work this way :
#RequestMapping(value = "/print", method = RequestMethod.POST)
public String printPost(#ModelAttribute("printerentity") #Valid PrinterEntity print, Model model, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "redirect:/formPrinter";
}
model.addAttribute("printed", print.getName());
model.addAttribute("printerentity", new PrinterEntity());
return "index";
}
And the form :
<form method="post" th:action="#{/print}" th:object="${printerentity}">
<input type="text" th:field="*{name}"/>
<button type="submit">Valider</button>
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>
</form>
What am I doing wrong ?
EDIT : It seems that when I have an error, I dont pass in the controller code :o =>
#RequestMapping(value = "/print", method = RequestMethod.POST)
public String printPost(#ModelAttribute("printerentity") #Valid PrinterEntity print, Model model, BindingResult bindingResult) {
System.out.println("I dont passe here when error but I m redirected");
if (bindingResult.hasErrors()) {
return "formPrinter";
}
model.addAttribute("printed", print.getName());
model.addAttribute("printerentity", new PrinterEntity());
return "index";
}
thanks for advance
How should I do to manage my redirection correctly ?
When you redirect a request, then the current request destroyed, and a new request object is created to process the request, so as per Sotirios Delimanolis has mentioned in comment, that model attributes are request attributes, which are available for per request only, If you want to store model attributes in the HTTP session between requests use #SessionAttributes, or a FlashAttributes.
As per your html form you have:
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>
you mean you want to show validation errors in the same page, then don't redirect return the same view.
if (bindingResult.hasErrors()) {
//return "redirect:/formPrinter";
return "your html form view";
}
then, on your view you can render all validation error messages like:
<p th:each="err : ${#fields.errors('*')}" th:text="${err}"></p>
I had the same problem and it was solved by reordering the parameters in my #PostMapping method to (#Valid #ModelAttribute Form form, BindingResult bindingResult, Model model)
When the params were in the same order as your controller (#Valid #ModelAttribute Form form, Model model, BindingResult bindingResult) I was also redirected to /error without the controller #PostMethod being called.
Is there an easy way in Spring MVC 3.x to display form error messages (obtained by JSR303 validation), before submiting the form ?
Consider the example code at the end of this post.
The end-user is supposed to edit forms in which the initial data is already invalid.
Errors are properly displayed when the form is submitted (POST method), but not on initial form display (GET method).
Is there an easy way to display the errors on initial form display (GET method) ? (Is there a way to re-use the form:errors tag for this purpose?)
JSP View form1.jsp:
<%# page session="true" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html><body>
<form:form commandName="form1" method="post">
<s:bind path="*">
<c:if test="${status.error}">
<div style="color: red;">There are errors:</div>
<form:errors /><br />
</c:if>
</s:bind>
<form:label path="field1" >Field1:</form:label>
<form:input path="field1" />
<form:errors path="field1" cssStyle="color: red;"/>
<br />
<form:label path="field2" >Field2:</form:label>
<form:input path="field2" />
<form:errors path="field2" cssStyle="color: red;"/>
<br />
<form:button name="submit">Ok</form:button>
</form:form>
</body></html>
Controller:
#Controller #SessionAttributes("form1")
public class Form1Controller {
#ModelAttribute("form1") public Form1Bean createForm1() { return new Form1Bean(); }
#RequestMapping(value = "/form1/edit", method = RequestMethod.GET)
public String getEdit(Model model) {
// here we pretend to get form1 from database, and store it in session.
// form1 in database may have invalid field values.
// Perform a JSR-303 validation here ?
// MAIN QUESTION: What's the easy way to add errors to model and display them ?
return "/form1";
}
#RequestMapping(value = "/form1/edit", method = RequestMethod.POST)
public String postEdit(#Valid #ModelAttribute("form1") Form1Bean form1, BindingResult result, Model model) {
if (result.hasErrors()) {
return "/form1";
} else {
return "redirect:/done";
}
}
}
Backing Bean:
public class Form1Bean {
#Size(min=4,max=10) private String field1; // getters and setters ommited for brevity
#Size(min=4,max=10) private String field2;
public Form1Bean() {
this.field1 = "bad"; this.field2="good"; // start with an invalid field1
}
//...
}
Edit: After the interpreting the answer from #jb-nizet, here is the complete controller source:
#Controller #SessionAttributes("form1")
public class Form1Controller {
#Autowired org.springframework.validation.Validator validator;
#ModelAttribute("form1") public Form1Bean createForm1() { return new Form1Bean(); }
#RequestMapping(value = "/form1/edit", method = RequestMethod.GET)
public String getEdit(#ModelAttribute("form1") Form1Bean form1, Errors errors, Model model) {
// here we pretend to get form1 from database, and store it in session.
// form1 in database may have invalid field values.
validator.validate(form1, errors);
return "/form1";
}
#RequestMapping(value = "/form1/edit", method = RequestMethod.POST)
public String postEdit(#Valid #ModelAttribute("form1") Form1Bean form1, BindingResult result, Model model) {
if (result.hasErrors()) {
return "/form1";
} else {
return "redirect:/done";
}
}
}
Made a few tests, and it seems to work! Than you #jb-nizet
Not tested, but as I understand the documentation, you would just have to inject an object of type org.springframework.validation.Validator in your controller, create and bind an Errors instance as explained in Add Error on GET METHOD Spring annotated controller, and invoke the validator's validate() method, passing the form and the Errors as argument.