Spring MVC
Last Updated on: January 19, 2021 pm
Spring MVC Overview
- Framework for building web application in Java.
- Based on Model-View-Controller design pattern.
- Leverages features of the Core Spring Framework (IoC, DI).
Components
- A set of web pages to layout UI Components
- A collection of Spring beans
- Spring Configuration (XML, Annotations or Java)
Front Controller
- Known as DispatchServlet
- Part of the Spring Framework
- Already developed by Spring Dev Team
You need to create:
- Model Objects
- View Templates
- Controller Classes
Controller
Contains your business logic
- Handle the request
- Store/Retrieve data(db, web service)
- Place data in model
Send to appropriate view template
Model
Contains your data
Store/Retrieve data via backend systems
- Database, web service, etc…
- Use a Spring bean if you like
Place your data in a model
- Data can be Java Object or colletion.
Like your luggage.
View Template
Most common is JSP and JSTL.
Developer creates a page.
Display data.
Spring MVC Configuration Process
Preparation
- Create a Java EE Application in IntelliJ IDEA.
Copy the two XML files to WEB-INF directory.
Open Project Structure
- Add Spring Module to the project.
- Download Spring Library to the project.
- Do the same thing to the Spring MVC library. ** Click the **Apply and OK.
- Open the Project Structure again. Fix the problems in the Problems section.
- Move the lib directory to the WEB-INF. Add two JSTL.jar to lib as well.
- Open Project Structure again and modify the version path of the two dependencies to ./web/WEB-INF/lib.
- Create view directory.
Part 1
Add configuration to file: WEB-INF/web.xml
Configure Spring MVC Dispatch Servlet
Set up URL mappings to Spring MVC Dispatcher Servlet
For every URL coming, pass it off to the DispatchServlet.
The Servlet-name here should match the servlet-name in the above Servlet.
Part 2
Add configuration to servlet.xml.
- Add support for Spring component scanning.
- Add support for conversion, formatting and validation.
Spring can perform conversion, and also formatting data and perform validation by adding this support.
- Configure Spring MVC View Resolver.
How do we display those pages? / Where are the pages located?
Prefix: 前缀
Suffix: 后缀
Example:
Create Controllers and Views
Create Controller class
1 |
|
Annotate class with @Controller.
@Controller inherits from @Component and it supports scanning.
Define Controller Methods
1 |
|
Add Request Mapping to Controller method
1 |
|
RequestMapping()
annotation maps a path to this given method, so you can define any method name.
Here, this request mapping will handle all kinds of requests, including get post and so on.
Return View Name
1 |
|
Spring will find teh view page by appending the prefix and suffix.
WEB-INF/view/main-menu.jsp
Develop View Page
main-menu.jsp
1 |
|
Read Form Data from Spring MVC
The browser goes to the website /showForm
.
This goes to the HelloWorld Controller.
The main purpose of the controller is to show helloworld-form.jsp
Key Point: use one HelloWorld Controller to process two RequestMappings.
Development Process
- Create Controller Class
1 |
|
- Show HTML form.
1 |
|
- Process HTML form.
1 |
|
Add Data to Spring Model
Passing model to your controller
Parameters in the Controller method:
HttpServletRequest
- Holds HTML form dataModel
- Container for your form dataHttpServletResponse
View Template - JSP
Add attribute name & attribute value.
model.addAttribute("message", result)
Example
1.Build your controller method
1 |
|
- Add the attribute to the view page.
1 |
|
Note: The attribute name msg
has to match the one in the controller method.
- Modify the JSP page name in the starting view page.
1 |
|
Request Params and Request Mappings
Bind Request Params
Instead of using HttpServletRequest
, use a different technique to read the form data. - An annotation
@RequestParam("paramName")
Process
Spring will read the param from the form request: studentName
Bind it the the variable that is given this annotation.
1 |
|
Controller Level Request Mapping
Add a controller level mapping to resolve some mapping conflicts.
1 |
|
Form Tags and Data Binding
Form Page Structure
1 |
|
Reference Spring MVC Form Tags
Specify the namespace st beginning of the JSP file.
1 |
|
Text Fields
Show Form
In Spring Controller:
- Before showing the form, we need to add a model attribute.
- This is the bean that will hold form data for the data binding.
Development Process
- Create the student class and generate the getters and setters.
- Create the student controller class.
1 |
|
- Create the HTML form.
1 |
|
- Create form processing code.
1 |
|
- Create confirmation page.
1 |
|
Use properties file to load data
- Create a properties file to store the countries.
New text file: WEB-INF/countries.properties
1 |
|
- Update header section for Spring config file. Replace the header content in the
spirng-mvc-demo-servlet.xml
1 |
|
- Load country options properties in the config file. Bean id = countryOptions
1 |
|
- Import the
java.util.Map
inStudentController.java
. And inject the properties into theStudentController.java
.
1 |
|
- Add country Options to the Spring MVC model and specify the attribute name: theCountryOptions
1 |
|
- Update the JSP view page to use the model attribute for drop down list.
1 |
|
Radio Buttons
- Update HTML form.
- Update Student Class - add getter and setter.
- Update confirmation page.
Example:
1 |
|
Check Box
Example:
1 |
|
Include jstl.core.jar
in your lib. And display the String array using:
1 |
|
Spring MVC Form Validation
Overview
Java’ Standard Bean Validation API
Spring supports the Bean Validation API. - Preferred method.
Features
- Required
- Length
- Numbers
- Regular Expressions
- Custom Validation
Annotations
- @NotNull
- @Min
- @Max
- @Size
- @Pattern
- @Future / @Past
Setup Dev Env
Go to Hibernate and click on Validator.
Download the zip file and unzip it.
Copy and paste the three jar files in ./dist
and four jar files in ./dist/required
to WEB-INF/lib
Required Field
Add validation rule to customer class.
1
2
3
4private String firstName;
@NotNull(message="is required")
@Size(min = 1, message="is required")
private String lastName;Display error msg to the HTML form.
1
2
3<br><br>
Last Name(*): <form:input path="lastName"/>
<form:errors path="lastName" cssClass="error"/>Perform validation in Controller Class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@RequestMapping("/showForm")
public String showForm(Model theModel){
theModel.addAttribute("customer", new Customer());
return "customer-form";
}
@RequestMapping("/processForm")
public String processForm(
// @Valid performs the validation rules on customer object
// Results of validation placed in the Binding Result.
@Valid @ModelAttribute("customer") Customer theCustomer,
BindingResult theBindingResult){
if(theBindingResult.hasErrors()){
return "customer-form";
}else{
return "customer-confirmation";
}
}Update Confirmation page.
1
2
3<body>
The Customer is Confirmed: ${customer.firstName} ${customer.lastName}
<br><br>@InitBinder
@InitBinder
works as a pre-processor.
It will pre-process each web request to the controller.
Method with this annotation will be executed.
1 |
|
WebDataBinder
StringTrimmerEditor
- A class defined in the Spring API, removes the leading and trailing white space.new StringTrimmerEditor(true)
- Trim the String tonull
if it’s all white space.dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
- for every String class, applyStringTrimmerEditor
Validate Number Range
1 |
|
Validate Regular Expression
1 |
|
How to make the Integer Field required
1 |
|
Solution: Convert the int variable to Integer
, otherwise there will be a conversion error,
The trimmer will trime the string to null string if it is all white spaces, so the string cannot be converted directly to primitive type int
, and we should use Integer
type, which can be converted from the String
type.
How to handle String input for Integer Field
Process
Create custom error message.
1
typeMismatch.customer.freePasses=Invalid Number
Create a folder
resources
undersrc
path, and create amessage.properties
file.Load custom error message to the spring-servlet.xml config file.
1
2
3
4
5<!-- Load custom message resources-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="resources.message" />
</bean>Deep Dive
Below is the BindingResult
with Error Msg:
1 |
|
According the Error Msg, we can custom different typeMismatch
in the messages.properties
:
typeMismatch.customer.freePasses
typeMismatch.freePasses
typeMismatch.java.lang.Integer
typeMismatch
- …
Custom Validation
Example
- Course Code must start with “LUV”
- Spring MVC calls the custom validation
- The validation returns a boolean value for pass or fail (T/F)
Custom Java Annotation
1 |
|
Process
Create @CourseCode annotation.
- Some annotations of the custome Annotation.
1
@Constraint(validatedBy = CourseCodeConstraintValidator.class)
CourseCodeConstraintValidator
- Helper class that contains business rules or validation logic.1
@Target({ElementType.METHOD, ElementType.FIELD })
Can apply our annotation to a method or a field.
1
@Retention(RetentionPolicy.RUNTIME)
Retain this annotation in the Java class file. Process it at runtime.
- Define attribtues and set default values.
1
2
3
4
5
6
7
8// define default course code
String value() default "LUV";
// define the default error msg
String message() default "Must start with LUV";
// define default groups
Class<?>[] groups() default {};
// define default payloads
Class<? extends Payload>[] payload() default {};Develop CourseCodeConstraintValidator.
1
2
3public class CourseCodeConstraintValidator
implements ConstraintValidator<CourseCode, String> {
}CourseCode
- Annotation NameString
- Type of data to validate against
1
2
3
4
5private String coursePrefix;
@Override
public void initialize(CourseCode theCourseCode) {
coursePrefix = theCourseCode.value();
}1
2
3
4
5
6
7
8@Override
public boolean isValid(String theCode, ConstraintValidatorContext theConstraintValidatorContext) {
if(theCode != null){
return theCode.startsWith(coursePrefix);
}else{
return true;
}
}Spring MVC will call the
isValid()
method at runtime.theCode
- HTML form data entered by the user.ConstraintValidatorContext
- Helper class for additional error messages.Method Body - Validation logic - Test if the form data starts with the provided course prefix.
Reference: Udemy, Spring & Hibernate for Beginners (including SpringBoot)