[snippets for spring boot]
application.properties
provides a sensible default property value for name.import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
On your application classpath (for example, inside your jar) you can have an application.properties
file that provides a sensible default property value for name. When running in a new environment, an application.properties
file can be provided outside of your jar that overrides the name.
For one-off testing, you can launch with a specific command line switch (for example, java -jar app.jar --name="Spring"
).
The values in application.properties
are filtered through the existing Environment when they are used, so you can refer back to previously defined values (for example, from System properties).
app.name=MyApp
app.description=${app.name} is a Spring Boot application
A setter may be omitted in the following cases:
Maps
, as long as they are initialized, need a getter but not necessarily a setter, since they can be mutated by the binder.Collections
and arrays
can be accessed either through an index (typically with YAML) or by using a single comma-separated value (properties).
Security
field in the preceding example), a setter is not required. If you want the binder to create the instance on the fly by using its default constructor, you need a setter.https://github.com/thymeleaf/thymeleaf-extras-springsecurity
The Thymeleaf Extras Spring Security library provides a dialect that allows integrating several authorization and authentication aspects of Spring Security (versions 3.x, 4.x and 5.x) into Thymeleaf-based applications. Features:
Thymeleaf-based equivalent to the Spring Security JSP tag library.
#authentication
and #authorization
for integrating Spring Security capabilities into Thymeleaf expressions.sec:authentication
and sec:authorized
for easier configuration of security.With this library, role-based access restrictions defined in Spring Security can be easily used:
<div sec:authorize="hasRole('ROLE_ADMIN')">
This will only be displayed if authenticated user has role ROLE_ADMIN.
</div>
The security-related objects can also be included in your normal Thymeleaf expressions:
<div th:text="${#authentication.name}">
The value of the "name" property of the authentication object should appear here.
</div>
Data pagination made easy with thymeleaf and spring data.
This is a dialect for Thymeleaf that provides some attributes to create pagination and sorting elements, bootstrap style, based on Spring Data.
Maven dependency:
<dependency>
<groupId>io.github.jpenren</groupId>
<artifactId>thymeleaf-spring-data-dialect</artifactId>
<version>3.4.0</version>
</dependency>
Add the Spring Data dialect to your existing Thymeleaf template engine:
templateEngine.addDialect(new SpringDataDialect()); // This line adds the dialect to Thymeleaf
If using Spring Boot you can add the following line and the ThymeleafAutoConfiguration class will add the dialect to the template engine.
@Bean
public SpringDataDialect springDataDialect() {
return new SpringDataDialect();
}
This will introduce the
sd
namespace, and the new attribute processors that you to use in your pages:pagination
,pagination-sort
,pagination-summary
,pagination-url
,page-object
,pagination-qualifier
andpage-size-selector
.
In your @Controller
@RequestMapping("/users")
public String list(ModelMap model, @SortDefault("username") Pageable pageable){
model.addAttribute("page", userService.find(pageable));
return "users/list";
}
Your html page looks like:
<table class="table table-striped table-hover">
<thead>
<tr>
<th><a class="sorted" sd:pagination-sort="username" >Username</a></th>
<th><a class="sorted" sd:pagination-sort="firstName" >First name</a></th>
<th>Last Name</th>
<th></th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${page}">
<th scope="row" th:text="${row.username}">Username</th>
<td th:text="${row.firstName}">Name</td>
<td th:text="${row.lastName}">Last Name</td>
<td><a href="#">edit</a></td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<div sd:pagination-summary="">info</div>
</div>
<div class="col-sm-6">
<nav class="pull-right">
<ul class="pagination" sd:pagination-split="7" sd:pagination="full">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
</div>
</div>
sd:pagination-split
to configure the number of links to show.<nav>
<ul class="pagination" sd:pagination="pager">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
<nav>
<ul class="pagination" sd:pagination="aligned-links">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
<div>
<span sd:pagination-summary="compact">info</span>
<div class="btn-group pager-compact" sd:pagination="compact-pager">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<a href="#" class="btn btn-default disabled"><span class="glyphicon glyphicon-chevron-left"></span></a>
<a href="#" class="btn btn-default"><span class="glyphicon glyphicon-chevron-right"></span></a>
</div>
</div>
Show <span sd:page-size-selector="default"></span> entries
Show <span sd:page-size-selector="javascript"></span> entries
<div class="btn-group dropup" sd:page-size-selector="dropdown"></div>
On your @Controller
@RequestMapping("/users")
public String list(ModelMap model, @Qualifier("foo") Pageable first, @Qualifier("bar") Pageable second){
model.addAttribute("page", userService.find(first));
model.addAttribute("barPage", userService.find(second));
return "users/list";
}
<div class="row">
<div class="col-md-6" sd:page-object="${page}" sd:pagination-qualifier="foo">
<div class="panel panel-default">
<div class="panel-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th><a class="sorted" sd:pagination-sort="username" >Username</a></th>
<th><a class="sorted" sd:pagination-sort="firstName" >First name</a></th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${page}">
<td th:text="${row.username}">First Name</td>
<td th:text="${row.firstName}">Last Name</td>
</tr>
</tbody>
</table>
<nav>
<ul class="pagination" sd:pagination="full">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
</div>
</div>
</div>
<div class="col-md-6" sd:page-object="${barPage}" sd:pagination-qualifier="bar">
<div class="panel panel-default">
<div class="panel-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th><a class="sorted" sd:pagination-sort="username" >Username</a></th>
<th><a class="sorted" sd:pagination-sort="firstName" >First name</a></th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${barPage}">
<td th:text="${row.username}">First Name</td>
<td th:text="${row.firstName}">Last Name</td>
</tr>
</tbody>
</table>
<nav class="">
<ul class="pagination" sd:pagination="full">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
By default SpringDataDialect search in the request for the attribute "page" or if one attribute of type org.springframework.data.domain.Page<?>
exists. To use another model attribute, use sd:page-object="${attrName}
"
sd:pagination-url
tag:<nav>
<ul class="pagination" sd:pagination="pager" sd:pagination-url="@{/some-url}">
<!-- Pagination created by SpringDataDialect, this content is just for mockup -->
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
The generated HTML has the CSS classes sorted
, sorted-asc
and sorted-desc
. This allows you to quite easily add some custom CSS to have sort icons in the table headers.
table.table thead .sorted:after{
display: inline-block;
font-family: 'FontAwesome';
opacity: 0.8;
margin-left: 1em;
}
table.table thead .sorted.sorted-desc:after{
content: "\f15e";
}
table.table thead .sorted.sorted-asc:after{
content: "\f15d";
}
.sorted-desc::after, .sorted-asc::after {
float: right;
}
.sorted-desc::after{
content:"\25BC";
}
.sorted-asc::after{
content: "\25B2";
}