06 Spring Boot 3 Spring MVC
06 Spring Boot 3 Spring MVC
© luv2code LLC
What is Thymeleaf?
• Thymeleaf is a Java templating engine www.thymeleaf.org
Separate project
Unrelated to spring.io
Output
fi
2. Develop Spring MVC Controller
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Based on this,
@Controller
public class DemoController {
@GetMapping("/")
public String sayHello(Model theModel) {
return "helloworld";
}
}
src/main/resources/templates/helloworld.html
fi
• src/main/resources/templates
<body>
<p th:text="'Time on the server is ' + ${theDate}" />
</body>
</html>
2
Thymeleaf
expression
<body>
<p th:text="'Time on the server is ' + ${theDate}" />
</body>
</html>
2
Thymeleaf
expression
www.thymeleaf.org
© luv2code LLC
Let's Apply CSS Styles to our Page
Before After
Time on the server is Sat Jan 05 11:42:13 EST 2019 Time on the server is Sat Jan 05 11:42:13 EST 2019
font-style: italic;
color: green;
fi
• We'll cover both options in this video
fi
2. Reference CSS in Thymeleaf template
custom sub-directorie
static/css
static/images
static/js
etc
src/main/resources
static
File: demo.css
css
.funny {
demo.css font-style: italic;
color: green;
}
Can be any sub-directory nam
e
</head>
src/main/resources
static
css
demo.css
<body>
<p th:text="'Time on the server is ' + ${theDate}" class="funny" />
</body>
/src/main/resources
1. /META-INF/resources
2. /resources
Search order: top-down
3. /static
4. /public
fi
<head>
… …
</head>
<head>
… …
… …
</head>
© luv2code LLC
The Need for Validation
required eld
fi
s
• Spring Boot and Thymeleaf also support the Bean Validation API
http://www.beanvalidation.org
Validation Feature
required
validate length
validate numbers
custom validation
2. required eld
fi
3. validate number range: min, max
5. custom validation
Required Fields
© luv2code LLC
Required Fields
customer-form.html
Customer
Custome
Controller
Customer
customer-con rmation.html
fi
www.luv2code.com © luv2code LLC
Development Process Step-
By-S
tep
1. Create Customer class and add validation rules
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
// getter/setter methods
…
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.ui.Model
@GetMapping("/"
)
return "customer-form"
;
name value
}
>
Customer class
<br><br>
>
>
<span th:if="${#fields.hasErrors('lastName')}
"
th:errors="*{lastName} "
class="error"></span>
<br><br>
</form>
BindingResult theBindingResult)
return "customer-form"
else
{
return "customer-confirmation"
<body>
>
</body>
</html>
@InitBinder
© luv2code LLC
White Space
• Our previous example had a problem with white spac
fi
www.luv2code.com © luv2code LLC
@InitBinder Adva
nce d
• @InitBinder annotation works as a pre-processor
@InitBinde
r
dataBinder.registerCustomEditor(String.class, stringTrimmerEditor)
© luv2code LLC
Validate a Number Range
fi
• User can only enter a range: 0 to 10
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.Max
// getter/setter method
s
Regular Expressions
© luv2code LLC
Regular Expressions Adva
nce d
fi
n
fi
• Regular Expressions is like its own language (advanced topic
• https://docs.oracle.com/javase/tutorial/essential/regex/
fi
• User can only enter 5 chars / digit
// getter/setter method
s
© luv2code LLC
Spring MVC Validatio
© luv2code LLC
Development Process Step-
By-S
tep
src/resources/messages.properties
Custom Validation
© luv2code LLC
Custom Validation Demo
fi
…
✤ @CourseCod
e
b. Create CourseCodeConstraintValidator
Usage Example
@Constraint(validatedBy = CourseCodeConstraintValidator.class
@Retention(RetentionPolicy.RUNTIME
..
.
@Constraint(validatedBy = CourseCodeConstraintValidator.class
@Retention(RetentionPolicy.RUNTIME
..
.
@Constraint(validatedBy = CourseCodeConstraintValidator.class
@Retention(RetentionPolicy.RUNTIME
..
.
import jakarta.validation.ConstraintValidatorContext
fi
;
@Override
public void initialize(CourseCode theCourseCode)
coursePre x = theCourseCode.value()
fi
;
@Override
public boolean isValid(String theCode,
ConstraintValidatorContext theConstraintValidatorContext)
boolean result
;
if (theCode != null)
{
result = theCode.startsWith(coursePre x)
fi
;
else
{
result = true
;
return result
;