Building a Simple CRUD Application Using Spring Boot, Angular, and Jasper Report [Part 1 - Spring Boot Section]

Building a Simple CRUD Application Using Spring Boot, Angular, and Jasper Report [Part 1 - Spring Boot Section]


In today's fast-paced digital world, developing efficient and robust web applications is crucial for businesses to stay competitive. This tutorial will guide you through building a simple CRUD (Create, Read, Update, Delete) application using Spring Boot for the backend, Angular for the frontend, and Jasper Reports for generating dynamic reports. I've divided this topic into three parts: Spring Boot, Jasper Reports, and Angular. By the end of these articles, you'll have a solid understanding of how to integrate these powerful technologies to create a seamless and functional web application. Whether you're a beginner looking to expand your skills or an experienced developer seeking to explore new tools, this step-by-step guide will provide you with the knowledge and confidence to build your own CRUD application. Let's get started!


Preparation

This guide will provide a step-by-step walkthrough of the process. However, before we delve into that, it's crucial to ensure that your development environment is equipped with the required prerequisites. Here is a list of the prerequisites for this tutorial:

  1. Java Development Kit (JDK)
  2. Node.js & npm
  3. Integrated Development Environment (IDE)
  4. Docker (I use Docker for the sake of simplicity. If you don’t, you can skip this and set it up manually.)

Initialize Spring Boot Project

Initialize the project through the IDE or using the Spring Initializr . Next open the project and add dependencies by replacing the `<dependencies></dependencies>` section in the pom.xml file with the following code.

<dependencies>

	   <dependency>
	      <groupId>net.sf.jasperreports</groupId>
	      <artifactId>jasperreports</artifactId>
	      <version>6.21.3</version>
	   </dependency>


	   <dependency>
	      <groupId>org.springframework.boot</groupId>
	      <artifactId>spring-boot-starter-thymeleaf</artifactId>
	      <version>3.3.0</version>
	   </dependency>


	   <dependency>
	      <groupId>org.springdoc</groupId>
	      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
	      <version>2.5.0</version>
	   </dependency>


		<dependency>
			<groupId>io.minio</groupId>
			<artifactId>minio</artifactId>
			<version>8.5.10</version>
		</dependency>


		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-jackson</artifactId>
			<version>0.12.5</version>
		</dependency>


		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-impl</artifactId>
			<version>0.12.5</version>
		</dependency>


		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt-api</artifactId>
			<version>0.12.5</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
			<version>3.2.5</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>3.2.5</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
			<version>3.2.5</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
			<version>3.2.5</version>
		</dependency>

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>        

After updating your pom.xml, run the following Maven command to update your project dependencies.

mvn clean install        

Next, open the project and configure the database and other settings in the ./src/main/resources/application.properties file.

application.properties


Create ./src/main/resources/message.properties

message.properties



Initialize Dockerfile

Create file ./Dockerfile and check line33 to ensure it matches your project identity as specified in ./pom.xml file

Dockerfile

Here's a breakdown of what each section does:

  1. FROM maven:3.8.5-openjdk-17 AS build: This sets the base image for the build stage to an official Maven image.
  2. WORKDIR /app: This sets the working directory inside the container to /app.
  3. COPY pom.xml .: This copies the pom.xml file from the host machine to the container's /app directory.
  4. COPY src ./src: This copies the source code from the host machine to the container's /app/src directory.
  5. COPY src/main/resources/application.properties.docker ./src/main/resources/application.properties: This copies a specific application.properties file from the host machine to the container's /app/src/main/resources directory.
  6. RUN mvn clean package -DskipTests: This runs the Maven build command to compile and package the application, skipping tests.
  7. FROM openjdk:23-ea-17-jdk-bullseye: This sets the base image for the runtime stage to an official OpenJDK image.
  8. RUN apt-get update && apt-get install -y --no-install-recommends fontconfig && apt-get install -y --no-install-recommends wget cabextract && wget https://downloads.sourceforge.net/corefonts/arial32.exe && cabextract -q arial32.exe -d /usr/share/fonts/truetype/msttcorefonts && fc-cache -f -v && apt-get clean && rm -rf /var/lib/apt/lists/* arial32.exe: This installs necessary packages including Microsoft core fonts.
  9. WORKDIR /app: This sets the working directory inside the container to /app.
  10. COPY --from=build /app/target/simple-online-shop-0.0.1-SNAPSHOT.jar app.jar: This copies the compiled jar file from the previous build stage to the container's /app directory.
  11. EXPOSE 8080: This exposes port 8080 inside the container.
  12. ENTRYPOINT ["java", "-jar", "app.jar"]: This sets the command to run when the container starts, which is to execute the Java jar file.


Initialize SQL Init File

Create simple file. This file will be executed within docker.

simple-online-shop.sql

Initialize Docker Compose File

Create ./docker-compose.yml file. For development purposes, you can comment out the app section and uncomment it when you are ready to dockerize your app.

You can run this using the following command, and your development environment will be ready to use.

docker compose up -d        

Build Back End Apps

My project has the groupId "com.etwicaksono" and the artifactId "simple-online-shop," so my program files are placed in ./src/main/java/com/etwicaksono/simpleonlineshop directory. Your path may be a bit different from mine, so adjust it based on your setup.


Configuration

A configuration class in Spring Boot is a class annotated with @Configuration that is used to define beans and settings for your Spring application context. These classes are crucial for setting up and managing various aspects of your application, such as data sources, security, and custom beans.

Here are the key concepts related to configuration in Spring Boot:

  1. @Configuration: This annotation marks the class as a source of bean definitions. It is similar to a traditional XML configuration file but allows you to use Java code to configure your application.
  2. @Bean: Methods within a @Configuration class can be annotated with @Bean to indicate that they produce a bean to be managed by the Spring container. The method name typically serves as the bean name.
  3. Dependency Injection: Configuration classes often use dependency injection to wire together various components and dependencies required by the application.
  4. Environment-Specific Configuration: You can use profiles to create environment-specific configuration classes that are activated based on the current active profile (e.g., development, production).

Configuration classes in Spring Boot provide a flexible and powerful way to define beans and settings for your application. By using the @Configuration and @Bean annotations, you can manage your application's dependencies and configurations efficiently. Profiles allow for environment-specific configurations, ensuring that your application can adapt to different environments seamlessly.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/config to store all configurations we use. Create the following files as our configurations.

./src/main/java/com/etwicaksono/simpleonlineshop/config/MinioConfig.java

MinioConfig.java

./src/main/java/com/etwicaksono/simpleonlineshop/config/SecurityConfig.java

SecurityConfig.java


./src/main/java/com/etwicaksono/simpleonlineshop/config/SwaggerConfig.java

SwaggerConfig.java



Entities

In Java Spring Boot, an entity is a lightweight, persistent domain object that typically represents a table in a relational database. Each instance of the entity corresponds to a row in the table. Entities are used in conjunction with the Java Persistence API (JPA) to map the object-oriented domain model to a relational database.

Here are some key points about entities in Java Spring Boot:

  1. Entity Annotation: An entity class is usually annotated with @Entity to mark it as a JPA entity. This annotation indicates that the class should be mapped to a database table.
  2. Table Annotation: The @Table annotation is optional and is used to specify the name of the database table to be used for mapping. If not specified, the table name defaults to the class name.
  3. Id Annotation: The @Id annotation is used to denote the primary key of the entity. This is typically combined with the @GeneratedValue annotation to specify how the primary key should be generated (e.g., auto-incremented).
  4. Column Annotation: The @Column annotation is used to specify the details of the column to which a field will be mapped. It can define attributes such as the column name, length, and nullable status.
  5. Relationships: Entities can define relationships to other entities using annotations like @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany. These annotations help in mapping the associations between different entities.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/entity to store all entities we use. Create the following files as our entities.

./src/main/java/com/etwicaksono/simpleonlineshop/entity/CustomerEntity.java

CustomerEntity.java


./src/main/java/com/etwicaksono/simpleonlineshop/entity/ItemEntity.java

ItemEntity.java


./src/main/java/com/etwicaksono/simpleonlineshop/entity/OrderEntity.java

OrderEntity.java



Repositories

In Spring Boot, repositories are used to encapsulate the logic required to access data sources. Repositories provide a convenient, consistent way to interact with databases, making CRUD (Create, Read, Update, Delete) operations straightforward and reducing boilerplate code. Spring Data JPA is a powerful feature of Spring Boot that simplifies the development of repositories.

Here are the key concepts related to repositories in Spring Boot:

  1. Repository Interfaces: Repositories are typically defined as interfaces that extend Spring Data JPA repository interfaces such as JpaRepository, CrudRepository, or PagingAndSortingRepository. These interfaces provide generic methods for CRUD operations and pagination.
  2. No Implementation Required: By extending the repository interfaces provided by Spring Data JPA, you get a fully functional repository without having to write any implementation code. Spring Data JPA dynamically generates the implementation at runtime.
  3. Custom Queries: In addition to the standard CRUD operations, Spring Data JPA allows you to define custom queries using method names, JPQL (Java Persistence Query Language), or native SQL queries. Method names can follow specific conventions to generate queries automatically.
  4. Annotations: Various annotations like @Query can be used to define custom queries directly in the repository interface.
  5. Transaction Management: Repositories automatically handle transaction management, ensuring that database operations are executed within appropriate transaction contexts.

Repositories in Spring Boot provide a powerful and easy way to handle data access. By extending the repository interfaces provided by Spring Data JPA, you can leverage a wide range of data access methods without writing boilerplate code. Custom queries and automatic transaction management further enhance the capabilities of repositories, making data access efficient and manageable.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/repository to store all repositories we use. Create the following files as our repositories.

./src/main/java/com/etwicaksono/simpleonlineshop/repository/CustomerRepository.java

CustomerRepository.java


./src/main/java/com/etwicaksono/simpleonlineshop/repository/ItemRepository.java

ItemRepository.java


./src/main/java/com/etwicaksono/simpleonlineshop/repository/OrderRepository.java

OrderRepository.java

Utils

In Spring Boot, utility classes (often referred to as "utils") serve as a collection of static methods or reusable code that can be used across the application. These classes are designed to perform common tasks that are needed in multiple places, helping to reduce code duplication and improve maintainability.

Here are the key concepts related to utils in Spring Boot:

  1. Reusable Code: Utility classes encapsulate common functionality that can be reused across different parts of the application. This includes tasks such as string manipulation, date formatting, validation, and more.
  2. Static Methods: Utility methods are typically static, meaning they can be called without creating an instance of the utility class. This makes them easy to use and access from anywhere in the application.
  3. No State: Utility classes should generally be stateless. They should not maintain any state between method calls, which ensures they are thread-safe and can be used in concurrent environments.
  4. Organized Structure: Grouping related utility methods together in a single class helps keep the codebase organized and easier to navigate.

Utility classes in Spring Boot provide a centralized way to implement common, reusable functionality. By encapsulating frequently used methods in utility classes, you can keep your codebase clean, maintainable, and DRY (Don't Repeat Yourself). These classes should be stateless and consist of static methods, ensuring they are easy to use and thread-safe.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/utils to store all utils we use. Create the following files as our utils.

./src/main/java/com/etwicaksono/simpleonlineshop/utils/Constants.java

Constants.java


./src/main/java/com/etwicaksono/simpleonlineshop/utils/ResponseUtil.java

ResponseUtil.java

Data Transfer Object (DTO)

In Spring Boot, a Data Transfer Object (DTO) is an object that carries data between processes. DTOs are often used to encapsulate the data for transfer between the client and server, particularly in RESTful APIs. They serve as a simple, plain Java object (POJO) designed to hold data with no business logic.

Here are the key concepts related to dto in Spring Boot:

  1. Purpose:DTOs are used to transfer data between layers of an application. They are particularly useful in separating the internal domain models from the external data representations.
  2. Separation of Concerns:Using DTOs helps maintain a clear separation between the data representation and the business logic. This separation enhances maintainability and allows for easier modifications to the data structure without affecting the business logic.
  3. Serialization:DTOs are often serialized to JSON or XML for transfer over HTTP in RESTful APIs. They can be easily mapped from or to these formats using libraries like Jackson.
  4. Validation:DTOs can include validation annotations to ensure that the data being transferred meets certain criteria before it is processed by the application.

DTOs in Spring Boot are essential for transferring data between different layers of the application, particularly between the client and server in RESTful APIs. By using DTOs, you achieve a clear separation of concerns, facilitate data validation, and simplify data serialization and deserialization. DTOs help maintain clean and maintainable code, ensuring that the internal domain models remain decoupled from external data representations.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/dto to store all dto we use. Create the following files as our dto.

General DTO

./src/main/java/com/etwicaksono/simpleonlineshop/dto/Pagination.java

Pagination.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/WebResponse.java

WebResponse.java


Customer DTO

./src/main/java/com/etwicaksono/simpleonlineshop/dto/customer/CreateCustomerRequest.java

CreateCustomerRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/customer/CustomerDto.java

CustomerDto.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/customer/GetListCustomerRequest.java

GetListCustomerRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/customer/UpdateCustomerRequest.java

UpdateCustomerRequest.java


Item DTO

./src/main/java/com/etwicaksono/simpleonlineshop/dto/item/CreateItemRequest.java

CreateItemRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/item/GetListItemRequest.java

GetListItemRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/item/ItemDto.java

ItemDto.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/item/UpdateItemRequest.java

UpdateItemRequest.java


Order DTO

./src/main/java/com/etwicaksono/simpleonlineshop/dto/order/CreateOrderRequest.java

CreateOrderRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/order/GetListOrderRequest.java

GetListOrderRequest.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/order/OrderDto.java

OrderDto.java


./src/main/java/com/etwicaksono/simpleonlineshop/dto/order/UpdateOrderRequest.java

UpdateOrderRequest.java

Specification

In Spring Boot, specifications are used to build dynamic queries for retrieving data from a database. The Specification pattern, provided by Spring Data JPA, allows you to create complex, flexible, and type-safe queries using a programmatic approach. This is particularly useful when you need to build queries based on multiple criteria that can vary at runtime.

Here are the key concepts related to specification in Spring Boot:

  1. Specification Interface: The Specification interface, part of Spring Data JPA, allows you to define a query condition. It takes a generic type that represents the entity type for which the specification is created.
  2. Predicate: A Predicate is a core part of the specification and is used to encapsulate a single condition in the query. Specifications are built by combining multiple predicates using logical operators.
  3. Criteria API: The Criteria API is used within the Specification to create type-safe queries. It provides a way to build queries programmatically using CriteriaBuilder and CriteriaQuery.
  4. Combining Specifications: Multiple specifications can be combined using logical operators such as AND and OR to form complex queries.

Specifications in Spring Boot, provided by Spring Data JPA, offer a powerful and flexible way to build dynamic and type-safe queries. By using the Specification interface and the Criteria API, you can create complex queries based on multiple criteria that can be easily combined and reused. This approach promotes clean, maintainable, and flexible code, making it easier to handle complex querying requirements in your application.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/service/specification to store all specifications we use. Create the following files as our specifications.

./src/main/java/com/etwicaksono/simpleonlineshop/service/specification/CustomerSpecification.java

CustomerSpecification.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/specification/ItemSpecification.java

ItemSpecification.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/specification/OrderSpecification.java

OrderSpecification.java

Service

In Spring Boot, the service layer is responsible for encapsulating the business logic of the application. It serves as an intermediary between the controller layer, which handles incoming HTTP requests, and the repository layer, which interacts with the database. By centralizing business logic in services, you ensure a clean separation of concerns, making your code more modular, testable, and maintainable.

Here are the key concepts related to service in Spring Boot:

  1. Business Logic: The service layer contains the core business logic of the application. This includes processing data, applying business rules, and orchestrating operations involving multiple components.
  2. Transaction Management: Services often manage transactions, ensuring that a sequence of operations either completes successfully as a whole or is rolled back in case of errors. This is typically achieved using the @Transactional annotation.
  3. Service Interface and Implementation: It is common practice to define a service interface and its implementation. This promotes loose coupling and makes it easier to switch implementations if needed.
  4. Dependency Injection: Services typically use dependency injection to access repositories and other services. This is usually done via constructor injection or field injection.

We'll use directory ./src/main/java/com/etwicaksono/simpleonlineshop/service to store all services we use. Create the following files as our services.

./src/main/java/com/etwicaksono/simpleonlineshop/service/ValidationService.java

ValidationService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/ReportService.java

ReportService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/MinioService.java

MinioService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/CustomerService.java

CustomerService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/CustomerServiceImpl.java

CustomerServiceImpl.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/ItemService.java

ItemService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/ItemServiceImpl.java

ItemServiceImpl.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/OrderService.java

OrderService.java


./src/main/java/com/etwicaksono/simpleonlineshop/service/OrderServiceImpl.java

OrderServiceImpl.java



Controller

A controller in Spring Boot is a central part of the Spring MVC framework, responsible for handling web requests and mapping them to appropriate service methods. It acts as an intermediary between the client and the server-side logic, processing incoming requests, invoking business logic, and returning appropriate responses.

Key components and features of a Spring Boot controller include:

  1. Annotation-Driven: Controllers are typically annotated with @RestController or @Controller. The @RestController annotation combines @Controller and @ResponseBody, indicating that the controller returns data directly as a response, often in JSON or XML format. The @Controller annotation is used when the controller returns a view (e.g., an HTML page).
  2. Request Mapping: Methods within a controller are annotated with @RequestMapping or its specialized variants like @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping. These annotations define the URI patterns and HTTP methods that the method should respond to.
  3. Path Variables and Request Parameters: Controllers can handle dynamic URLs using @PathVariable and query parameters with @RequestParam. This allows the extraction of data from the URL or query string and its use within the method.
  4. Request and Response Handling: Controllers use method parameters to handle various aspects of the request, such as headers (@RequestHeader), cookies (@CookieValue), and request bodies (@RequestBody). They can return various response types, including simple data types, objects (automatically converted to JSON/XML), and ResponseEntity for detailed control over HTTP responses.
  5. Exception Handling: Controllers can include error handling using @ExceptionHandler methods, allowing the customization of responses when exceptions occur. Additionally, @ControllerAdvice can be used for global exception handling across multiple controllers.
  6. Validation: Controllers support input validation through JSR-303/JSR-380 annotations on method parameters, combined with @Valid or @Validated, to ensure that incoming data meets predefined constraints.
  7. Cross-Origin Resource Sharing (CORS): Controllers can handle CORS configurations using @CrossOrigin annotations, allowing them to specify which domains are permitted to interact with the endpoints.
  8. Content Negotiation: Controllers support content negotiation to return different response formats based on client preferences, leveraging the Accept header and appropriate message converters.

By encapsulating the routing logic, input validation, and interaction with service layers, controllers in Spring Boot provide a clean, organized way to handle web requests and responses, facilitating the development of robust and maintainable web applications.

Create directory ./src/main/java/com/etwicaksono/simpleonlineshop/service/controller to store all controllers we use. Create the following files as our controllers.

./src/main/java/com/etwicaksono/simpleonlineshop/controller/CustomerController.java

CustomerController.java

Look at line 256; there is a file for generating reports, which we will discuss further in the Jasper Reports section. As a temporary solution, you can take Customer_List.jasper file from my repository.

./src/main/java/com/etwicaksono/simpleonlineshop/controller/ErrorController.java

This class is for overriding the default error handling provided by Spring Boot.

ErrorController.java


./src/main/java/com/etwicaksono/simpleonlineshop/controller/ItemController.java

ItemController.java

Look at line 240; there is a file for generating reports, which we will discuss further in the Jasper Reports section. As a temporary solution, you can take Item_List.jasper file from my repository.

./src/main/java/com/etwicaksono/simpleonlineshop/controller/OrderController.java

OrderController.java

Look at line 218; there is a file for generating reports, which we will discuss further in the Jasper Reports section. As a temporary solution, you can take Order_List.jasper file from my repository.

./src/main/java/com/etwicaksono/simpleonlineshop/controller/RootController.java

RootController.java

We use rootHandler to show first page, it needs a html file to show up, so let's create ./src/main/resources/templates/welcome.html file.

welcome.html

Run the Application

Navigate to Project Directory: Open a terminal (Command Prompt on Windows, Terminal on macOS/Linux) and navigate to the root directory of your Spring Boot project.

cd /path/to/your/project        

Build the Project (if necessary): If your project hasn't been built yet or if you've made changes to the code, you may need to build it using Maven or Gradle. Spring Boot projects typically use Maven by default.

# For Maven
mvn clean package  -DskipTests        

Run the Application: Once the project is built (or if it's already built), you can run the Spring Boot application using the java command:

java -jar target/your-project-name.jar        

Replace your-project-name.jar with the actual name of your JAR file generated by Maven or Gradle.

Here is the appearance when it runs successfully.

CMD result

Try to open https://localhost:8080/ , and you should see this page.

home page


Try to click documentation link and you should see Swagger page

swagger page


Congratulations! You've successfully completed this tutorial. By now, you should have a solid understanding of how to build a simple CRUD application using Spring Boot for the backend. We hope this guide has provided you with valuable insights and practical skills to apply in your projects.

Thank you for following along, and happy coding! If you have any questions or need further assistance, feel free to reach out. Keep exploring and building amazing applications!

You can check out my repository for this project here . Feel free to clone it, explore the code, and use it as a reference for your own projects.

Stay tuned for our next article, where we will dive into Jasper Reports for dynamic report generation. We'll guide you through setting up Jasper Reports in your project, designing report templates, and integrating them with your data sources. See you in the next tutorial!

要查看或添加评论,请登录

社区洞察

其他会员也浏览了