Skip to content

12. Conclusion

This document described the development of a MVC web application using the [Spring MVC] and [Spring Boot] frameworks: an application whose HTML pages are generated by the server, using [Thymeleaf] views, without the [JavaScript] framework on the client side. He followed the [ASP.NET Core MVC] course step by step, which itself builds on the courses [NestJS] and Introduction to ASP.NET MVC by Example: controllers and routing to views, forms, internationalization, security, and data access, followed by a comprehensive case study.

The same 28 examples and the same application were thus written using three frameworks: [TypeScript], [C#], and [Java]. The concepts are the same; only the names and mechanisms differ. Correspondences between [ASP.NET Core MVC] and [Spring MVC]:

ASP.NET Core MVC
Spring MVC (Spring Boot 4)
[Program.cs] (services and middleware)
class [@SpringBootApplication], classes [@Configuration], and methods [@Bean]
project file [.csproj], packages [NuGet]
file [pom.xml], starters [Maven]
[appsettings.json], [IConfiguration], options
[application.properties], [@Value], records [@ConfigurationProperties]
Dependency injection: [AddSingleton], [AddScoped], [AddTransient]
Beans: [@Service], [@Component], [@Bean], default singletons
[Controller], [[HttpGet]], [[HttpPost]], [IActionResult]
[@Controller], [@GetMapping], [@PostMapping], view name or [redirect:...]
model link, [[Required]], [[Range]]...
template link, [@NotBlank], [@Min], [@Max]... ([Bean Validation])
[ModelState.IsValid] and form redispatch
[@Valid], [BindingResult], and form redispatch
views [Razor] ([.cshtml]), [_Layout.cshtml], [_ViewStart.cshtml]
views [Thymeleaf] ([.html]), template via [th:replace]
partial views, Tag Helpers, parent class of view
fragments ([th:fragment]), [@ControllerAdvice], and [@ModelAttribute]
[TempData] (in an encrypted cookie)
Flash attributes ([RedirectAttributes]), in the session or a cookie
middleware, action and exception filters
servlet filters, interceptors, [@ControllerAdvice], [ErrorController]
[JwtBearer], [[Authorize(Roles = ...)]]
[Spring Security]: [SecurityFilterChain], resource server, [@PreAuthorize]
dictionaries JSON, [@T(...)], [UseRequestLocalization]
JSON dictionaries read by a [MessageSource], [#{...}], [LocaleResolver]
[Entity Framework Core], [DbContext], [LINQ]
[Spring Data JPA] and [Hibernate], [JpaRepository] interfaces, derived queries, [JPQL]
[BeginTransactionAsync], [CommitAsync]
[@Transactional], [TransactionTemplate]
[[ConcurrencyCheck]] and manually enhanced version
[@Version], managed by [Hibernate]
[dotnet run], [dotnet watch]
[mvnw spring-boot:run], [Spring Boot DevTools]

Regarding [ASP.NET Core], the key point to note is:

  • [Spring Boot] configures the application based on the available libraries: simply adding a starter is enough to obtain a web server, a view engine, a data source, or a chain of security filters, which can then be configured via properties or by declaring custom beans. This is very efficient, provided you know what [Spring Boot] has done for you: the startup log and the [DEBUG] level help you figure this out;
  • much of the behavior relies on proxies: [@Transactional] or [@PreAuthorize] only act when a method is called from another bean. It’s important to know this so you aren’t caught off guard;
  • [Spring Data JPA] reduces the DAO layer to declarations: an interface, method names that describe the queries, and, if necessary, [JPQL] queries. The optimistic lock ([@Version]) and the translation of database errors into [Spring] exceptions are provided;
  • [Spring Security] is more verbose than the attributes of [[Authorize]] in [ASP.NET Core], but everything is configurable in [Java], in the same place: access rules for URL, token reading, redirects, logout, and [CSRF] protection;
  • [Thymeleaf] views are valid HTML pages that a browser can display as-is; they contain only expressions, no [Java] code, which keeps them simple. On the other hand, they are not compiled: an error in an expression only becomes apparent when the page is displayed, not during compilation as with [Razor].

The case study shows that a classic HTML application, without the essential [JavaScript], remains a simple and robust solution: each page is a URL, the browser’s “Back” button works, and the server controls everything. The limited use of [JavaScript] (confirmation windows) enhances the user experience without being necessary for the application to function.

For more information, see the documentation for [Spring Framework] (docs.spring.io/spring-framework/reference), as well as the documentation for [Spring Boot] (docs.spring.io/spring-boot), [Spring Security] (docs.spring.io/spring-security/reference), and [Spring Data JPA] (docs.spring.io/spring-data/jpa/reference), the [Thymeleaf] site (thymeleaf.org), and compare this application to its counterparts [ASP.NET Core MVC] and [NestJS].