ReviewIn the previous section, we have laid down the functional specs of the application. In this section, we will discuss the project's structure, write the Java classes, and organize them in layers.
Table of ContentsPart 1: Introduction and Functional Specs
Part 2: Java classes
Part 3: XML configuration
Part 4: HTML Files
Part 5: Running the Application
Project StructureOur application is a Maven project and therefore follows Maven structure. As we create the classes, we've organized them in logical layers: domain, repository, service, and controller.
Here's a preview of our project's structure:
Domain LayerThis layer contains two domain classes, User and Role. They represent our database tables, user and role respectively. Because we're developing a JPA-based repository, both classes must be annotated with JPA annotations.
Specifying the entity name inside the @Entity is not required. However, I've encountered instances where the tables are created in lowercase and uppercase, i.e user and USER. For consistency, I've specified them here.
Controller LayerThis layer contains two controllers, AccessController and MediatorController.
- AccessController is responsible for handling access related requests, mainly login and logout requests
- MediatorController is responsible for handling requests to common pages such as user and admin pages
Service LayerThis layer contains a single service, CustomUserDetailsService. Its main purpose is to retrieve user information from our custom database and translate that user information into a format that Spring Security understands. Take note of the helper methods provided within this class.
What's the logic here?
- We must implement UserDetailsService because we have a custom database
- loadUserByUsername method must return an object that implements the UserDetails interface
- We must map our domain org.krams.domain.User to org.springframework.security.core.userdetails.User
- We must map numerical roles as SimpleGrantedAuthority objects
- We are responsible for interpreting what each numerical role value represents
- ROLE_USER and ROLE_ADMIN are abitrary values we assigned to numerical values
Repository LayerThis layer contains a single interface, UserRepository. And this is our data access object (DAO). With the help of Spring Data JPA, Spring will automatically provide the actual implementation.
What is Spring Data JPA?
Spring JPA is part of the umbrella Spring Data project that makes it easy to easily implement JPA based repositories.
Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that's actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.
Utility classesTraceInterceptor class is an AOP-based utility class to help us debug our application. This is a subclass of CustomizableTraceInterceptor (see Spring Data JPA FAQ)
NextIn the next section, we will focus on the configuration files and create them accordingly. Click here to proceed.
Share the joy:
Subscribe by reader Subscribe by email Share