In this post we will learn about using Spring Form Tags
, Form Validation using JSR-303 validation annotations
, hibernate-validators
, providing internationalization support using MessageSource
and accessing static resources (e.g. CSS, javascript, images) in our views using ResourceHandlerRegistry
, all using annotation-based configuration. Let’s get going.
we will create a simple application containing a student registration form, on form submission validating the user-input via JSR-303 validation annotations, overriding default messages using internationalized validation messages through properties files and also access the static resources (e.g. applying Bootstrap CSS to our pages).
Please note that JSR303 is a specification and hibernate-validator we are using in this post is an implementation, which also provides few of it’s own validation annotations not included in specification.
Following technologies being used:
Let’s begin.
Following will be the final project structure:
Let’s now add the content mentioned in above structure explaining each in detail.
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.websystique.springmvc</groupId> <artifactId>Spring4MVCFormValidationExample</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>Spring4MVCFormValidationExample</name> <properties> <springframework.version>4.0.6.RELEASE</springframework.version> <hibernate.validator.version>5.1.2.Final</hibernate.validator.version> <javax.validation.version>1.1.0.Final</javax.validation.version> </properties> <dependencies> <!-- Spring dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> <!-- jsr303 validation dependencies--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>${javax.validation.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> </dependency> <!-- Servlet dependencies --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <warSourceDirectory>src/main/webapp</warSourceDirectory> <warName>Spring4MVCFormValidationExample</warName> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </pluginManagement> <finalName>Spring4MVCFormValidationExample</finalName> </build> </project>
First thing to notice here is the maven-war-plugin
declaration. As we are using full annotation configuration, we don’t even include web.xml, so we will need to configure this plugin in order to avoid maven failure to build war package. On Validation part, validation-api
represents the specification, while hibernate-validator
is an implementation of this specification. hibernate-validator also provides few of it’s own annotations (@Email, @NotEmpty, etc..) which are not part of the specification.
Along with that, we have also included JSP/Servlet/Jstl dependencies which we will be needing as we are going to use servlet api’s and jstl view in our code. In general, containers might already contains these libraries, so we can set the scope as ‘provided’ for them in pom.xml.
In addition, I’ve also separately downloaded bootstrap.css just to demonstrate how to use resource handling in annotation based configuration.
This domain object will acts as a backing bean to the form holding data user will provide via form submission. We will annotate the properties(with validation annotations) which we want to be validated.
com.websystique.springmvc.model.Student
package com.websystique.springmvc.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.format.annotation.DateTimeFormat; public class Student implements Serializable { @Size(min=3, max=30) private String firstName; @Size(min=3, max=30) private String lastName; @NotEmpty private String sex; @DateTimeFormat(pattern="dd/MM/yyyy") @Past @NotNull private Date dob; @Email @NotEmpty private String email; @NotEmpty private String section; @NotEmpty private String country; private boolean firstAttempt; @NotEmpty private List<String> subjects = new ArrayList<String>(); public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getDob() { return dob; } public void setDob(Date dob) { this.dob = dob; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getSection() { return section; } public void setSection(String section) { this.section = section; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public boolean isFirstAttempt() { return firstAttempt; } public void setFirstAttempt(boolean firstAttempt) { this.firstAttempt = firstAttempt; } public List<String> getSubjects() { return subjects; } public void setSubjects(List<String> subjects) { this.subjects = subjects; } @Override public String toString() { return "Student [firstName=" + firstName + ", lastName=" + lastName + ", sex=" + sex + ", dob=" + dob + ", email=" + email + ", section=" + section + ", country=" + country + ", firstAttempt=" + firstAttempt + ", subjects=" + subjects + "]"; } }
In above code, @Size
, @Past
& @NotNull
are standard annotations while @NotEmpty
& @Email
are not part of specification.
Add the controller which will serve the GET and POST request.
com.websystique.springmvc.controller.HelloWorldController
package com.websystique.springmvc.controller; import java.util.ArrayList; import java.util.List; import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.websystique.springmvc.model.Student; @Controller @RequestMapping("/") public class HelloWorldController { /* * This method will serve as default GET handler. * */ @RequestMapping(method = RequestMethod.GET) public String newRegistration(ModelMap model) { Student student = new Student(); model.addAttribute("student", student); return "enroll"; } /* * This method will be called on form submission, handling POST request * It also validates the user input */ @RequestMapping(method = RequestMethod.POST) public String saveRegistration(@Valid Student student, BindingResult result, ModelMap model){ if(result.hasErrors()) { return "enroll"; } model.addAttribute("success", "Dear "+ student.getFirstName()+" , your Registration completed successfully"); return "success"; } /* * Method used to populate the Section list in view. * Note that here you can call external systems to provide real data. */ @ModelAttribute("sections") public List<String> initializeSections() { List<String> sections = new ArrayList<String>(); sections.add("Graduate"); sections.add("Post Graduate"); sections.add("Research"); return sections; } /* * Method used to populate the country list in view. * Note that here you can call external systems to provide real data. */ @ModelAttribute("countries") public List<String> initializeCountries() { List<String> countries = new ArrayList<String>(); countries.add("USA"); countries.add("CANADA"); countries.add("FRANCE"); countries.add("GERMANY"); countries.add("ITALY"); countries.add("OTHER"); return countries; } /* * Method used to populate the subjects list in view. * Note that here you can call external systems to provide real data. */ @ModelAttribute("subjects") public List<String> initializeSubjects() { List<String> subjects = new ArrayList<String>(); subjects.add("Physics"); subjects.add("Chemistry"); subjects.add("Life Science"); subjects.add("Political Science"); subjects.add("Computer Science"); subjects.add("Mathmatics"); return subjects; } }
@Controller
indicates that this class is a controller handling the requests with pattern mapped by @RequestMapping
.Here with ‘/’, it is serving as default controller. Method newRegistration
is fairly simple, annotated with @RequestMethod.GET
serving default GET requests, adding the model object to serve as data-holder of form , and presenting the page containing the blank form.
Method initializeSections, initializeCountries & initializeSubjects are simply creating request level objects whose values will be used in view/jsp.
Method saveRegistration
is annotated with @RequestMethod.POST
, and will handle the form-submission POST requests.Notice the parameters and their orders in this method. @Valid
asks spring to validate the associated object(student). BindingResult
contains the outcome of this validation and any error that might have occurred during this validation. Notice that BindingResult must come right after the validated object else spring won’t be able to validate and an exception been thrown.
Note that in case of validation failure, default/ generalized error messages are shown on screen which may not be desirable. Instead, you can override this behavior providing internationalized messages
specific to each field. To do that, we need to configure MessageSource
in application configuration class and provide properties files containing actual messages which we will do next.
com.websystique.springmvc.configuration.HelloWorldConfiguration
package com.websystique.springmvc.configuration; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.websystique.springmvc") public class HelloWorldConfiguration extends WebMvcConfigurerAdapter { /* * Configure View Resolver */ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } /* * Configure ResourceHandlers to serve static resources like CSS/ Javascript etc... * */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/static/"); } /* * Configure MessageSource to provide internationalized messages * */ @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; } }
@Configuration
indicates that this class contains one or more bean methods annotated with @Bean
producing bean manageable by spring container.@EnableWebMvc
is equivalent to mvc:annotation-driven
in XML. It enables support for @Controller-annotated classes that use @RequestMapping
to map incoming requests to specific method. @ComponentScan
is equivalent to context:component-scan base-package="..."
providing with where to look for spring managed beans/classes.
Method viewResolver
configures a view resolver to identify the real view. Method addResourceHandlers
configures the ResourceHandler for static resources. CSS, JavaScript, images etc are static resources your pages needs.Above configuration says that all resource requests starting with /static/ will be served from /static/ folder under webapp. In this example, we will put all the css files under /static/css inside webapp directory. Note that this method is defined in WebMvcConfigurerAdapter
so we needed to extend this class to override this method in order to register our static resources.
Method messageSource
configures a Message bundle to support [internationalized] messages from properties file. Notice the parameter provided (messages) to baseName method. Spring will search for a file named messages.properties in application class path. Let’s add that file:
src/main/resources/messages.properties
Size.student.firstName=First Name must be between {2} and {1} characters long Size.student.lastName=Last Name must be between {2} and {1} characters long NotEmpty.student.sex=Please specify your gender NotNull.student.dob=Date of birth can not be blank Past.student.dob=Date of birth must be in the past Email.student.email=Please provide a valid Email address NotEmpty.student.email=Email can not be blank NotEmpty.student.country=Please select your country NotEmpty.student.section=Please select your section NotEmpty.student.subjects=Please select at least one subject typeMismatch=Invalid format
Notice that above message follows a specific pattern
{ValidationAnnotationClass}.{modelObject}.{fieldName}
Additionally, based on specific annotation (e.g. @Size) you can also pass the arguments to these messages using {0},{1},..{i}
Above configuration in XML format will be
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.websystique.springmvc" /> <mvc:annotation-driven/> <mvc:resources mapping="/static/**" location="/static/" /> <mvc:default-servlet-handler /> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename"> <value>messages</value> </property> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/views/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
We will add two simple jsp pages. First one will contain a Form to receive input from user, and second one will show the success message to user once form input is validated successfully.
Below is the peace of code used to include static resources(bootstrap.css in our case)
<link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>
Notice the path to static resource. Since we have already configured ResourceHandlers in previous Step with /static/**, css file will be searched inside /static/ folder.
Complete JSP Files are shown below :
WEB-INF/views/enroll.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Student Enrollment Form</title> <link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link> <link href="<c:url value='/static/css/custom.css' />" rel="stylesheet"></link> </head> <body> <div class="form-container"> <h1>Enrollment Form</h1> <form:form method="POST" modelAttribute="student" class="form-horizontal"> <div class="row"> <div class="form-group col-md-12"> <label class="col-md-3 control-lable" >WEB-INF/views/success.jsp</code> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Student Enrollment Detail Confirmation</title> <link href="<c:url value='/static/css/custom.css' />" rel="stylesheet"></link> </head> <body> <div class="success"> Confirmation message : ${success} <br> We have also sent you a confirmation mail to your email address : ${student.email}. </div> </body> </html>
com.websystique.springmvc.configuration.HelloWorldInitializer
package com.websystique.springmvc.configuration; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class HelloWorldInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(HelloWorldConfiguration.class); ctx.setServletContext(container); ServletRegistration.Dynamic servlet = container.addServlet( "dispatcher", new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); } }
The content above resembles the content of web.xml from previous tutorials as we are using the front-controller DispatherServler
, assigning the mapping (url-pattern in xml) and instead of providing the path to spring configuration file(spring-servlet.xml) , here we are registering the Configuration Class.
UPDATE: Note that above class can be written even more concisely [and it’s the preferred way], by extending AbstractAnnotationConfigDispatcherServletInitializer
base class, as shown below:
package com.websystique.springmvc.configuration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { HelloWorldConfiguration.class }; } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
One thing to keep in mind that the Spring java based configuration api’s like WebApplicationInitializer depends on Servlet 3.0 containers
.So make sure you don’t have any web.xml with servlet declaration less than 3.0. For our case, we have removed web.xml file from our application.
Now build the war (either by eclipse as was mentioned in last tutorial) or via maven command line( mvn clean install
). Deploy the war to a Servlet 3.0 container . Since here i am using Tomcat, i will simply put this war file into tomcat webapps folder
and click on start.bat
inside tomcat bin directory.
Run the application
You get the initial page like below :
Now if you try to submit, you will get validation errors (with our user-defined message in message.properties)
Now Provide your sample inputs
Submit the form now:
That’s it.
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments
http://www.jeejava.com/spring-service-layer-bean-validation/
Hi Dear,
I have written below code but i am not getting properties file message.Please guide me.
---------AppConfig.java-------
@EnableWebMvc
@ComponentScan(basePackages ={"com.shiva.FormValidator"})
@Configuration
public class AppConfig {
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("/MVCFormValidation1/WebContent/WEB-INF/messages");
return messageSource;
}
}
--------StudentController.java--------
@Controller
public class StudentFormController {
@InitBinder
public void customizeBinding (WebDataBinder binder) {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
dateFormatter.setLenient(false);
binder.setDisallowedFields(new String[]{"roll"});
binder.registerCustomEditor(Date.class, "dob",new CustomDateEditor(dateFormatter, true));
binder.registerCustomEditor(String.class, "name",new StudentPropertyEditor());
}
@RequestMapping("/student")
public ModelAndView handleStudentForm()
{
ModelAndView mv=new ModelAndView("Student");
return mv;
}
@RequestMapping("MVCFormValidation1/studentDetails")
public ModelAndView handleDtudentDetails(@Valid@ModelAttribute("student1") Student student1,BindingResult result)
{
if(result.hasErrors())
{
ModelAndView mv=new ModelAndView("Student");
return mv;
}
ModelAndView mv=new ModelAndView("StudentDetails");
return mv;
}
}
------messages.properties--------
Size.student1.name=Name length must be in 2 to 10 charecter
Thanks,
Prabhat
Hi,
Can you please do an example using Spring MVC and angularJS when the form fields are being populated through a database? Thanks!
Hi Dimple, Have a look at Spring MVC + AngularJS & Spring Rest support, along with Spring & Hibernate. This should give you all what you need.
cool, thank you!
Hi There,
I downloaded the source code, tried running it using Tomcat. I am getting: HTTP Status 404 - /Spring4MVCFormValidationExample/
type Status report
message /Spring4MVCFormValidationExample/
description The requested resource is not available.
--------------------------------------------------------------------------------
Apache Tomcat/9.0.0.M17
The source code doesn't cme with web.xml and spring-servlet.xml as well. Do we create it?
Hello Dimple,
Probably you are having a deployment issue. Have a look at Setup tomcat+Eclipse, should fix the problem.
not found 404 error with this
http://localhost:8082/Spring4MVCFormValidationExample/
my port is 8082
Hi, probably you are having a deployment issue. Have a look at Setup tomcat+Eclipse, should fix the problem.
@websystique:disqus
Hi While deploying this application in tomcat I am getting HelloWorld as output can how to resolve this issue .
Ex. http://localhost:8080/FormValidate/
output HelloWorld . which is wrong. Please reply asap.
Hi, Saurabh, are you sure you are running the example from this post[ assuming you changed the name of your app]? There is nowhere a mapping returning 'Hello World'.
@websystique:disqus
Hi, I have run your application just i have changed the name of web application I think changing application name doesnt give wrong result,
but why its giving Hello World while typing this url .
http://localhost:8080/FormValidate/
Hi Saurabh,
If you haven't yet been able to figure out the issue, then please check your server's web.xml file. You probably have the welcome page set to index.jsp. Try commenting out this setting.
Shiji
I just downloaded this app and trying to deploy in tomcat but received an error.
86:
87: Section
88:
89:
90:
91:
92:
Stacktrace:] with root cause
java.lang.IllegalArgumentException: Attribute 'items' must be an array, a Collection or a Map
Hope you can let me know what the issue is.
I had this issue, to solve it I removed the web.xml file from the WEB-INF folder because we are configuring from java class.
Hi Krishnan, to start with, may i ask you to check if your tomcat setup is fine? Could you please follow Setup Tomcat with Eclipse and then try again?
Hi websys
Is a good a approach to use the 'Student' class that you are using in the form, to store in the database like an entity? If no, what is the best approach?
Hi Guilherme, it is certainly not preferable to expose your entities to view. Common approach to avoid this issue is to create the view objects [StudentView pojo, resembling your entities] which you can annotate with Spring's built-in validators for instance), use it on view, and then on save/update, copy the values from this view object into a real entity object [Student] and then call your DAO methods. It does create an extra layer but it also saves you from putting entities into UI. You can create set of mappers for your projects using Guava Function Interface, comes handy while copying property values of one class into another.
Hope this helps.
I code the Guava Function inside the Student pojo to don't expose this function to the view layer, or I code this on StudentView? Which is the best approach?
Hi Guilherme, Guava Function interface i mentioned above is just a helper to copy values from one class properties into another. You may create bunch of helper classes for your project. Something like this.
package com.yourpacage.ui.converter;
import com.google.common.base.Function;
public abstract class AbstractConverterFunction implements Function{
}
package com.yourpacage.ui.converter;
import com.yourpacage.model.Student;
import com.yourpacage.ui.to.StudentView;
public class ToStudentViewFunction extends AbstractConverterFunction{
@Override
public StudentView apply(Student entity) {
if(entity == null){
return null;
}
StudentView view = new StudentView();
view.setId(entity.getId());
view.setName(entity.getName());
return view;
}
}
Now, this ToStudentViewFunction class should be used in your service class. To keep things clean, you can create an extra service layer which takes care of this translation.
package com.yourpackage.ui.toservice;
import java.util.Arrays;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import com.google.common.collect.Lists;
@Service("studentViewService")
@Transactional
public class StudentViewServiceImpl implements StudentViewService{
@Autowired
StudentService studentService;
private ToStudentViewFunction viewFunction = new ToStudentViewFunction();
@Override
public StudentView findById(Integer id) {
return viewFunction.apply(studentService.findById(id));
}
@Override
public void create(StudentView studentView) {
if(studentView!= null){
Student student = new Student();
student.setName(studentView.getName());
studentService.persist(student);
studentView.setId(student.getId());
}
}
@Override
public void update(StudentView studentView) {
if(studentView!= null){
Student student = studentService.findById(studentView.getId());
student.setName(studentView.getName());
}
}
}
Then in controller, instead of injecting StudentService class, you should be injecting StudentViewService.
Hope it clears your doubts.
Thanks for the reply websys. I will try this now and will let you know!
One question that I have, its best approach to validate the forms and data on front-end before send to server, validate on server, or both ?
Hi Guilherme, Recommended approach is to use both client-side and server side validation.You can't simply rely only on client side validation.
Nice article. I am trying to validation inside the modal window using annotation, window always closed before validation . Do you have any suggestion ?
Hi Kalpana,
This example don't have the same setup like your particular example but i suppose you may intercept the form submission and skip the default behavior (which closes the form). And then in your error handler (which will be the case as there were server side validation error), display message to client, while in success handler, just simply close the modal window. A good link doing something similar can be found here.
If it does not help, you may want to share some runable code so that we can try to fix the issue together.
thank you.