Shopping project application with Spring boot and Ionic Part 1

Getting Started | Building an Application with Spring Boot




Build an application gyms with Spring boot and Angular use Jpa

Objective:

In this project we want to build an application shopping with spring boot and ionic. the project content Objects User, Shopping, Category, Product and Cart the Admin can add all information after login and the user can choose a product to add in his cart also he can save the product to his profile.


Used Skills in this project:

Java, SpringBoot, MicroServices, REST WebServices, JPA, Hibernate, OrikaBeanMapper, MySQL Database, Maven, Ionic, GitHub, SpringBoot Embedded Tomcat Server, STS-Eclipse IDE


Tools to be used

° Use any IDE to develop the Spring and Hibernate project. It may be STS/Eclipse/Netbeans. Here, we are using STS (Spring Tool Suite).

° Mysql for the database.

° Use any IDE to develop the Angular project. It may be Visual Studio Code/Sublime. Here, we are using Visual Studio Code.

° Server: Apache Tomcat/JBoss/Glassfish/Weblogic/Websphere.


Spring MVC

Spring MVC is the primary web framework built on the Servlet API. It is build on the popular MVC design pattern. MVC (Model-View-Controller) is a software architecture pattern, which separates application into three areas: model, view, and controller. The model represents a Java object carrying data. The view represents the visualization of the data that the model contains. The controller controls the data flow into model object and updates the view when the data changes. It separates the view and model.


Spring Boot Architecture



Spring Boot is a module of the Spring Framework. It is used to create stand-alone, production-grade Spring Based Applications with minimum efforts. It is developed on top of the core Spring Framework.



Introduction mysql to database

MySQL is a database management system that allows you to manage relational databases. It is open source software backed by Oracle. It means you can use MySQL without paying a dime. Also, if you want, you can change its source code to suit your needs. MySQL can run on various platforms UNIX, Linux, Windows, etc. You can install it on a server or even in a desktop. Besides, MySQL is reliable, scalable, and fast.



Introduction to the POM

POM A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target; the source directory, which is src/main/java; the test source directory, which is src/main/java; and so on. When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.

pom.xml

    
  
  
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0>/modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> </parent> <groupId>com.shopping-app</groupId> <artifactId>shopping-app</artifactId> <version>0.0.1-SNAPSHOT</version> <name>shopping-app</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>ma.glasnost.orika</groupId> <artifactId>orika-core</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

Properties File

Properties files are used to keep ‘N’ number of properties in a single file to run the application in a different environment. In Spring Boot, properties are kept in the application.properties file under the classpath.

The application.properties file is located in the src/main/resources directory. The code for sample application.properties


We need to create database name it shopping-app

src/main/resources/application.properties

    
  
spring.datasource.url=jdbc:mysql://localhost:3306/shopping-app?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC spring.datasource.username=root spring.activemq.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.hibernate.ddl-auto=create-drop server.port=8080

Class Diagram



Modals / Objects

We need to create five entities

- Cart

- Category

- Product

- Shopping

- User


Here, we are creating an Entity

Cart.java This object content id, name, count, price, total, added and relational @ManyToOne with User

src/main/java/com/shpping/model/Cart.java):



package com.shoppingapp.modal; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity public class Cart { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private int count; private double price; private double total; @Temporal(TemporalType.TIMESTAMP) private Date added; @ManyToOne private User user; public Cart() { super(); } public Cart(String name, int count, double price, double total, Date added, User user) { super(); this.name = name; this.count = count; this.price = price; this.total = total; this.added = added; this.user = user; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getTotal() { return total; } public void setTotal(double total) { this.total = total; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getAdded() { return added; } public void setAdded(Date added) { this.added = added; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }

Here, we are creating an Entity

Category.java This object content id, name, logo, expanded and relational @ManyToOne with Shopping and @OneToMany with Product We need to create a method addProductToCategory

src/main/java/com/shoppingapp/model/Category.java):



package com.shoppingapp.modal; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @Entity public class Category { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private String logo; private boolean expanded; @OneToMany(cascade = CascadeType.ALL, mappedBy = "category") private List<Product> products; @ManyToOne private Shopping shopping; public Category() { super(); } public Category(String name, String logo, List<Product> products, Shopping shopping) { super(); this.name = name; this.logo = logo; this.products = products; this.shopping = shopping; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLogo() { return logo; } public void setLogo(String logo) { this.logo = logo; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } public Shopping getShopping() { return shopping; } public void setShopping(Shopping shopping) { this.shopping = shopping; } public void addProductToCategory(Product product) { if(getProducts() == null) { this.products = new ArrayList<>(); } getProducts().add(product); product.setCategory(this); } }

Here, we are creating an Entity

Product.java This object content id, name, description, price, image, created and relational @ManyToOne with Category

src/main/java/com/shoppingapp/model/Product.java):



package com.shoppingapp.modal; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity public class Product { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private String description; private double price; private String image; @Temporal(TemporalType.TIMESTAMP) private Date created; @ManyToOne private Category category; public Product() { super(); } public Product(String name, String description, double price, String image, Date created, Category category) { super(); this.name = name; this.description = description; this.price = price; this.image = image; this.created = created; this.category = category; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getImage() { return image; } public voidsetImage(String image) { this.image = image; } public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } }

Here, we are creating an Entity

Shopping.java This object content id, name, expanded and relational @ManyToOne with User and @OneToMany with Category We need to create a method addCategoryToShopping

src/main/java/com/shoppingapp/model/Shopping.java):



package com.shoppingapp.modal; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @Entity public class Shopping { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private boolean expanded; @ManyToOne private User user; @OneToMany(cascade = CascadeType.ALL, mappedBy = "shopping") private List<Category> categories; public Shopping() { super (); } public Shopping(String name, boolean expanded, User user, List<Category> categories) { super(); this.name = name; this.expanded = expanded; this.user = user; this.categories = categories; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public List<Category> getCategories() { return categories; } public void setCategories(List<Category> categories) { this.categories = categories; } public void addCategoryToShopping(Category category) { if(getCategories() == null) { this.categories = new ArrayList<>(); } getCategories().add(category); category.setShopping(this); } }

Here, we are creating an Entity

User.java This object content id, username, password, admin and relational @OneToMany with Shopping and @OneToMany Cart We need to create two methods addCartToUser and addShoppingToUser

src/main/java/com/shoppingapp/model/User.java):



package com.shoppingapp.modal; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(unique = true) private String username; private String password; private boolean admin; @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") private List<Shopping> shoppings; @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") private List<Cart> carts; public User() { super(); } public User(String username, String password, boolean admin, List<Shopping> shoppings, List<Cart> carts) { super(); this.username = username; this.password = password; this.admin = admin; this.shoppings = shoppings; this.carts = carts; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isAdmin() { return admin; } public void setAdmin(boolean admin) { this.admin = admin; } public List<Shopping> getShoppings() { return shoppings; } public void setShoppings(List<Shopping> shoppings) { this.shoppings = shoppings; } public List<Cart> getCarts() { return carts; } public void setCarts(List<Cart> carts) { this.carts = carts; } public void addCartToUser(Cart cart) { if(getCarts() == null) { this.carts = new ArrayList<>(); } getCarts().add(cart); cart.setUser(this); } public void addShoppingToUser(Shopping shopping) { if (getShoppings()==null) { this.shoppings = new ArrayList<>(); } getShoppings().add(shopping); shopping.setUser(this); } }

OrikaBeanMapper

Orika is a Java Bean mapping framework that recursively copies data from one object to another. It can be very useful when developing multi-layered applications. While moving data objects back and forth between these layers it is common to find that we need to convert objects from one instance into another to accommodate different APIs.


OrikaBeanMapper.java In this class Orika to convert entity => DTO / DTO => entity

src/main/java/com/gym/model/OrikaBeanMapper.java):



package com.shoppingapp.manager.service; import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.impl.ConfigurableMapper; import ma.glasnost.orika.impl.DefaultMapperFactory; import ma.glasnost.orika.impl.generator.JavassistCompilerStrategy; import ma.glasnost.orika.metadata.ClassMapBuilder; import ma.glasnost.orika.unenhance.HibernateUnenhanceStrategy; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; @Component public class OrikaBeanMapper extends ConfigurableMapper { private MapperFactory factory; public OrikaBeanMapper() { super(false); init(); } /** * {@inheritDoc} */ @Override protected void configure(MapperFactory factory) { this.factory = factory; } private void registerClassMap(Class a, Class b) { this.factory.classMap(a, b).mapNulls(true).mapNullsInReverse(true).byDefault().register(); } /** * Register class map with fields to exclude * * @param a * @param b * @param excludeFields */ private void registerClassMap(Class a, Class b, String... excludeFields) { ClassMapBuilder builder = this.factory.classMap(a, b); for (String excludeField : excludeFields) { builder.exclude(excludeField); } builder.mapNulls(true).mapNullsInReverse(true).byDefault().register(); } /** * {@inheritDoc} */ @Override protected void configureFactoryBuilder(final DefaultMapperFactory.Builder factoryBuilder) { factoryBuilder.compilerStrategy(new JavassistCompilerStrategy()); factoryBuilder.unenhanceStrategy(new HibernateUnenhanceStrategy()); } /** * User Orika to convert entity => DTO / DTO => entity * * @param from * @param toClass * @param <T> * @param <U> return */ public <T, U> T convertDTO(U from, Class<T> toClass) { if (from == null) { return null; } return map(from, toClass); } /** * User Orika to convert entity => DTO / DTO => entity * * @param from * @param toClass * @param <T> * @param <U> * @return */ public <T, U> List<T> convertListDTO(Iterable<U> from, Class<T> toClass) { if (from == null) { return null; } return mapAsList(from, toClass); } public <T, U> Page<T> convertPageDTO(Page<U> from, Class<T> toClass) { if (from == null) { return null; } return from.map(entity -> factory.getMapperFacade().map(entity, toClass)); } }

The DTO Classes

- CartDto
- CategoryDto
- ProductDto
- ShoppingDto
- UserDto

What is a DTO?

DTO, which stands for Data Transfer Object, is a design pattern conceived to reduce the number of calls when working with remote interfaces. the main reason for using a Data Transfer Object is to batch up what would be multiple remote calls into a single one.


We'll handle the conversions that need to happen between the internal entities of a Spring application and the external DTOs (Data Transfer Objects) that are published back to the client.


Here, we are creating an Entity

CartDto.java This object content id, name, count, price, total

src/main/java/com/shpping/dto/CartDto.java):



package com.shoppingapp.dto; import java.util.Date; public class CartDto { private long id; private String name; private int count; private double price; private double total; private Date added; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getTotal() { return total; } public void setTotal(double total) { this.total = total; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getAdded() { return added; } public void setAdded(Date added) { this.added = added; } }

Here, we are creating an Entity

CategoryDto.java This object content id, name, logo, expanded and list of products form ProductDto

src/main/java/com/shoppingapp/dto/CategoryDto.java):



package com.shoppingapp.dto; import java.util.List; public class CategoryDto { private long id; private String name; private String logo; private boolean expanded; private List<ProductDto> products; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLogo() { return logo; } public void setLogo(String logo) { this.logo = logo; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public List<ProductDto> getProducts() { return products; } public void setProducts(List<ProductDto> products) { this.products = products; } }

Here, we are creating an Entity

ProductDto.java This object content id, name, description, price, image and created

src/main/java/com/shoppingapp/dto/ProductDto.java):



package com.shoppingapp.dto; import java.util.Date; public class ProductDto { private long id; private String name; private String description; private double price; private String image; private Date created; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } }

Here, we are creating an Entity

ShoppingDto.java This object content id, name, expanded and relational and a list categories from CategoryDto

src/main/java/com/shoppingapp/dto/ShoppingDto.java):



package com.shoppingapp.modal; import java.util.List; public class ShoppingDto { private long id; private String name; private boolean expanded; private User user; private List<Category> categories; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public List<CategoryDto> getCategories() { return categories; } public void setCategories(List<CategoryDto> categories) { this.categories = categories; } }

Here, we are creating an Entity

UserDto.java This object content id, username, password, admin and two lists from CartDo and ShoppingDto

src/main/java/com/shoppingapp/dto/UserDto.java):



package com.shoppingapp.dto; import java.util.List; public class User { private long id; private String username; private String password; private boolean admin; private List<ShoppingDto> shoppings; private List<CartDto> carts; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isAdmin() { return admin; } public void setAdmin(boolean admin) { this.admin = admin; } public List<ShoppingDto> getShoppings() { return shoppings; } public void setShoppings(List<ShoppingDto> shoppings) { this.shoppings = shoppings; } public List<CartDto> getCarts() { return carts; } public void setCarts(List<CartDto> carts) { this.carts = carts; } }

JPA Repositories

The JPA module of Spring Data contains a custom namespace that allows defining repository beans. It also contains certain features and element attributes that are special to JPA. Generally, the JPA repositories can be set up by using the repositories element, as shown in the following example:


Spring Repositories Spring has supported the concept of a repository for some time now. Repository is one of Spring's core stereotypes and you should plan on using them in your data access layer, regardless of your chosen data access layer API and framework.


Here, we are creating an interface CartDao

src/main/java/com/shoppingapp/dao/CartDao.java):



package com.shoppingapp.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.shoppingapp.modal.Cart; public interface CartDao extends JpaRepository<Cart, Long> { }

Here, we are creating an interface CategoryDao

src/main/java/com/shoppingapp/dao/CategoryDto.java):



package com.shoppingapp.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.shoppingapp.modal.Category; public interface CategoryDao extends JpaRepository<Category, Long> { }

Here, we are creating an interface ProductDao

src/main/java/com/shoppingapp/dao/ProductDao.java):



package com.shoppingapp.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.shoppingapp.modal.Product; public interface ProductDao extends JpaRepository<Product, Long> { }

Here, we are creating an interface ShoppingDao

src/main/java/com/shoppingapp/dao/ShoppingDao.java):



package com.shoppingapp.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.shoppingapp.modal.Shopping; public interface ShoppingDao extends JpaRepository<Shopping, Long> { }

Here, we are creating an interface UserDao

src/main/java/com/shoppingapp/dao/UserDao.java):



package com.shoppingapp.dao; import org.springframework.data.jpa.repository.JpaRepository; import com.shoppingapp.modal.User; public interface UserDao extends JpaRepository<User, Long> { }

The services

Service Components are the class file which contains @Service annotation. These class files are used to write business logic in a different layer, separated from @RestController class file. The logic for creating a service component class file is shown here


We will create two interfaces in service package:

- ShoppingService.java
- UserManService.java

What's the difference between @Component, @Repository and @Service

Can @Component, @Repository and @Service annotations be used interchangeably in Spring or do they provide any particular functionality besides acting as a notation device?


In other words, if I have a Service class and I change the annotation from @Service to @Component, will it still behave the same way?


Here, we are creating a service interface ShoppingService

ShoppingService.java This service interface content four methods


- addShoppingToUser
- addCategoryToShopping
- addCartToUser
- addProductToCategory

src/main/java/com/shoppingapp/service/ShoppingService.java):



package com.shoppingapp.service; import org.springframework.stereotype.Service; import com.shoppingapp.modal.Cart; import com.shoppingapp.modal.Category; import com.shoppingapp.modal.Product; import com.shoppingapp.modal.Shopping; import com.shoppingapp.modal.User; @Service public interface ShoppingService { Shopping addShoppingToUser(Shopping shopping, User user); Category addCategoryToShopping(Category category, Shopping shopping); Cart addCartToUser(Cart cart, User user); Product addProductToCategory(Product product, Category category); }

Here, we are creating a service interface UserService

ShoppingService.java This service interface content two methods


- addUser
- editUser

UserService.java This interface content two methds addUser and editUser

src/main/java/com/shoppingapp/service/UserService.java):



package com.shoppingapp.service; import org.springframework.stereotype.Service; import com.shoppingapp.modal.User; @Service public interface UserService { User addUser(User user); User editUser(User user, User existsUser); }

The Implements

Here we will use the implements for the Strategy pattern is a software design pattern commonly used for developing User interface that divides the related program logic into three interconnected elements.

The class that implements the Interface with @Component and @Transactional annotations is as shown −


- ShoppingServiceImpl.java
- UserManServiceImpl.java

Here, we are creating an implement class

ShoppingServiceImpl.java In this class we will implement ArbitrateService and @Override the methods addShoppingToUser, addCategoryToShopping, addCartToUser and addProductToCategory


src/main/java/com/shoppingapp/service/ShoppingServiceImpl.java):



package com.shoppingapp.service; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import com.shoppingapp.dao.CartDao; import com.shoppingapp.dao.CategoryDao; import com.shoppingapp.dao.ProductDao; import com.shoppingapp.dao.ShpoppongDao; import com.shoppingapp.modal.Cart; import com.shoppingapp.modal.Category; import com.shoppingapp.modal.Product; import com.shoppingapp.modal.Shopping; import com.shoppingapp.modal.User; @Transactional @Component public class ShoppingServiceImpl implements ShoppingService { @Autowired private CartDao cartDao; @Autowired private CategoryDao categoryDao; @Autowired private ProductDao productDao; @Autowired private ShpoppongDao shoppingDao; @Override public Category addCategoryToShopping(Category category, Shopping shopping) { if (shopping.getCategories().size()==0) { category.setExpanded(true); } else { category.setExpanded(false); } shopping.addCategoryToShopping(category); return categoryDao.save(category); } @Override public Cart addCartToUser(Cart cart, User user) { cart.setAdded(new Date()); user.addCartToUser(cart); return cartDao.save(cart); } @Override public Product addProductToCategory(Product product, Category category) { product.setCreated(new Date()); category.addProductToCategory(product); return productDao.save(product); } @Override public Shopping addShoppingToUser(Shopping shopping, User user) { if (user.getShoppings().size()==0) { shopping.setExpanded(true); } else { shopping.setExpanded(false); } user.addShoppingToUser(shopping); return shoppingDao.save(shopping); } }

Here, we are creating an implement class

UserServiceImpl.java In this class we will implement ArbitrateService and @Override the methods addUser and editUser


UserServiceImpl.java This object content id, name, and relational @ManyToOne with Sport and Gym

src/main/java/com/shoppingapp/service/UserServiceImpl.java):



package com.shoppingapp.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import com.shoppingapp.dao.UserDao; import com.shoppingapp.modal.User; @Transactional @Component public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public User addUser(User user) { if (user.getUsername().equals("admin") && user.getPassword().equals("admin") || user.getUsername().equals("drmas") && user.getPassword().equals("drmas")) { user.setAdmin(true); return userDao.save(user); } else { return userDao.save(user); } } @Override public User editUser(User user, User existsUser) { existsUser.setUsername(user.getUsername()); existsUser.setPassword(user.getPassword()); existsUser.setAdmin(user.isAdmin()); return userDao.save(existsUser); } }

The manager services

It stands for Implementation. It's a Java convention. Often in java (particularly J2EE) you will get an object from some factory, and then use it. That object's type is often given to you as an interface, so that you don't need to know the actual class, just its methods.


We'll be developing the classes managers services. One possible reason for every service class to have an interface is that it makes interactions with sophisticated frameworks (Spring, JEE) much simpler. This is because Java can simply generate interceptor objects against interfaces.


We will create two interfaces in manager.service package:

- ShoppingManagerService
- UserManagerService

Here, we are creating a service interface ShoppingManagerService

ShoppingManagerService.java This service interface content these methods


- addShoppingToUser
- addCategoryToShopping
- addCartToUser
- addProductToCategory
- findCategoriesToShopping
- findCategories
- findProductsToCategory
- findProducts

src/main/java/com/shoppingapp/manager/service/ShoppingManagerService.java):



package com.shoppingapp.manager.service; import java.util.List; import org.springframework.stereotype.Service; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.CategoryDto; import com.shoppingapp.dto.ProductDto; import com.shoppingapp.dto.ShoppingDto; @Service public interface ShoppingManagerService { CategoryDto addCategoryToShopping(CategoryDto categoryDto, long idUser); CartDto addCartToUser(CartDto cartDto, long idUser); ProductDto addProductToCategory(ProductDto productDto, long idCategory); CategoryDto addShoppingToUser(ShoppingDto shoppingDto, long idUser); List<CategoryDto> findCategoriesToShopping(long idShopping); List<CategoryDto> findCategories(); List<ProductDto> findProductsToCategory(long idCategory); List<ProductDto> findProducts(); }

Here, we are creating a service interface UserManagerService

UserManagerService.java This service interface content these methods


- addUser
- editUser
- deleteUser
- findCartsToUser
- findShoppingsToUser
- findUserById
- findUserByName

src/main/java/com/shoppingapp/model/UserManagerService.java):



package com.shoppingapp.manager.service; import org.springframework.stereotype.Service; import java.util.List; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.ShoppingDto; import com.shoppingapp.dto.UserDto; @Service public interface UserManagerService { UserDto addUser(UserDto userDto); UserDto editUser(UserDto userDto, long idUser); void deleteUser(long idUser); List<CartDto> findCartsToUser(long idUser); List<ShoppingDto> findShoppingsToUser(long idUser); UserDto findUserById(long idUser); UserDto findUserByName(String username); }

The managers classes implementation

An impl class is usually a class that implements the behaviour described by one of these interfaces. While the internal implementation class, With transactions configured, we can now annotation a bean with @Transactional and @Service either at the class or method level. Then conversion Entity to DTO. This is stands for Data Transfer Object and is a simple Plain Old Java Object which contains class properties and getters and settings methods for accessing those properties.


We will create seven interfaces in manager.service package:

Here, we are creating a class

ShoppingManagerServiceImpl.java In this class we will implement ShoppingManagerService and @Override the methods addUser, editUser, deleteUser, findCartsToUser, findShoppingsToUser, findUserById, findUserByName


src/main/java/com/shoppingapp/manager/service/ShoppingManagerServiceImpl.java):



package com.shoppingapp.manager.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.shoppingapp.dao.CategoryDao; import com.shoppingapp.dao.ProductDao; import com.shoppingapp.dao.ShpoppongDao; import com.shoppingapp.dao.UserDao; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.CategoryDto; import com.shoppingapp.dto.ProductDto; import com.shoppingapp.dto.ShoppingDto; import com.shoppingapp.modal.Cart; import com.shoppingapp.modal.Category; import com.shoppingapp.modal.Product; import com.shoppingapp.modal.Shopping; import com.shoppingapp.modal.User; import com.shoppingapp.service.ShoppingService; @Service @Transactional public class ShoppingManagerServiceImpl implements ShoppingManagerService { @Autowired private OrikaBeanMapper orikaBeanMapper; @Autowired private ShoppingService shoppingService; @Autowired private UserDao userDao; @Autowired private CategoryDao categoryDao; @Autowired private ShpoppongDao shoppingDao; @Autowired private ProductDao productDao; @Override public CategoryDto addCategoryToShopping(CategoryDto categoryDto, long idShopping) { Category category = orikaBeanMapper.map(categoryDto, Category.class); Shopping shopping = shoppingDao.findById(idShopping).orElse(null); return orikaBeanMapper.convertDTO(shoppingService.addCategoryToShopping(category, shopping), CategoryDto.class); } @Override public CartDto addCartToUser(CartDto cartDto, long idUser) { Cart cart = orikaBeanMapper.map(cartDto, Cart.class); User user = userDao.findById(idUser).orElse(null); return orikaBeanMapper.convertDTO(shoppingService.addCartToUser(cart, user), CartDto.class); } @Override public ProductDto addProductToCategory(ProductDto productDto, long idCategory) { Product product = orikaBeanMapper.map(productDto, Product.class); Category category = categoryDao.findById(idCategory).orElse(null); return orikaBeanMapper.convertDTO(shoppingService.addProductToCategory(product, category), ProductDto.class); } @Override public CategoryDto addShoppingToUser(ShoppingDto shoppingDto, long idUser) { Shopping shopping = orikaBeanMapper.map(shoppingDto, Shopping.class); User user = userDao.findById(idUser).orElse(null); return orikaBeanMapper.convertDTO(shoppingService.addShoppingToUser(shopping, user), CategoryDto.class); } @Override public List<CategoryDto> findCategoriesToShopping(long idShopping) { Shopping shopping = shoppingDao.findById(idShopping).orElse(null); List<Category> categories = shopping.getCategories(); return orikaBeanMapper.convertListDTO(categories, CategoryDto.class); } @Override public List<CategoryDto> findCategories() { List<Category> shoppings = categoryDao.findAll(); return orikaBeanMapper.convertListDTO(shoppings, CategoryDto.class); } @Override public List<ProductDto> findProductsToCategory(long idCategory) { Category category = categoryDao.findById(idCategory).orElse(null); List<Product> products = category.getProducts(); return orikaBeanMapper.convertListDTO(products, ProductDto.class); } @Override public List<ProductDto> findProducts() { List<Product> products = productDao.findAll(); return orikaBeanMapper.convertListDTO(products, ProductDto.class); } }

Here, we are creating an interface

UserManagerServiceImpl.java In this class we will implement UserManagerService and @Override the methods addUser, editUser, deleteUser, findCartsToUser, findShoppingsToUser, findUserById, findUserByName

src/main/java/com/shoppingapp/manager/service/UserManagerServiceImpl.java):



package com.shoppingapp.manager.service; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.shoppingapp.dao.UserDao; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.ShoppingDto; import com.shoppingapp.dto.UserDto; import com.shoppingapp.modal.Cart; import com.shoppingapp.modal.Shopping; import com.shoppingapp.modal.User; import com.shoppingapp.service.UserService; @@Transactional @Service public class UserManagerServiceImpl implements UserManagerService { @Autowired private OrikaBeanMapper orikaBeanMapper; @Autowired private UserService userService; @Autowired private UserDao userDao; @Override public UserDto addUser(UserDto userDto) { User user = orikaBeanMapper.map(userDto, User.class); return orikaBeanMapper.convertDTO(userService.addUser(user), UserDto.class); } @Override public UserDto editUser(UserDto userDto, long idUser) { User user = orikaBeanMapper.map(userDto, User.class); User existsUser = userDao.findById(idUser).orElse(null); return orikaBeanMapper.convertDTO(userService.editUser(user, existsUser), UserDto.class); } @Override public void deleteUser(long idUser) { userDao.deleteById(idUser); } @Override public List<CartDto> findCartsToUser(long idUser) { User existsUser = userDao.findById(idUser).orElse(null); List<Cart> carts = existsUser.getCarts(); return orikaBeanMapper.convertListDTO(carts, CartDto.class); } @Override public UserDto findUserById(long idUser) { return orikaBeanMapper.convertDTO(userDao.findById(idUser).orElse(null), UserDto.class); } @Override public UserDto findUserByName(String username) { Optional<User> user = userDao.findByUsername(username); if (user.isPresent()) { User user1 = user.get(); return orikaBeanMapper.convertDTO(user1, UserDto.class); } return null; } @Override public List<ShoppingDto> findShoppingsToUser(long idUser) { User existsUser = userDao.findById(idUser).orElse(null); List<Shopping> shoppings = existsUser.getShoppings(); return orikaBeanMapper.convertListDTO(shoppings, ShoppingDto.class); } }

@RestController API

@RestController is a convenience annotation for creating Restful controllers. It is a specialization of @Component and is autodetected through classpath scanning. It adds the @Controller and @ResponseBody annotations. It converts the response to JSON or XML. It does not work with the view technology, so the methods cannot return ModelAndView. It is typically used in combination with annotated handler methods based on the @RequestMapping annotation.


We will create two classes in controller package:

- ShoppingController
- UserController

Here, we are creating a controller class

ShoppingController.java We'll inject this bean into the ShoppingManagerService bean using @Autowired on the field definition: We need to add map requests with request mapping annotations e.g. @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping

src/main/java/com/shoppingapp/controller/ShoppingController.java):



package com.shoppingapp.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.CategoryDto; import com.shoppingapp.dto.ProductDto; import com.shoppingapp.dto.ShoppingDto; import com.shoppingapp.manager.service.ShoppingManagerService; @RestController @RequestMapping("api") @CrossOrigin(origins = "*") public class ShoppingController { @Autowired private ShoppingManagerService shoppingManagerService; @PostMapping("/addShoppingToUser/{idUser}") CategoryDto addShoppingToUser(@RequestBody ShoppingDto shoppingDto, @PathVariable long idUser) { return shoppingManagerService.addShoppingToUser(shoppingDto, idUser); } @PostMapping("/addCategoryToShopping/{idShopping}") CategoryDto addCategoryToShopping(@RequestBody CategoryDto categoryDto, @PathVariable long idShopping) { return shoppingManagerService.addCategoryToShopping(categoryDto, idShopping); } @PostMapping("/addCartToUser/{idUser}") CartDto addCartToUser(@RequestBody CartDto cartDto, @PathVariable long idUser) { return shoppingManagerService.addCartToUser(cartDto, idUser); } @PostMapping("/addProductToCategory/{idCategory}") ProductDto addProductToCategory(@RequestBody ProductDto productDto, @PathVariable long idCategory) { return shoppingManagerService.addProductToCategory(productDto, idCategory); } @GetMapping("/findCategoriesToShopping/{idShopping}") List<CategoryDto> findCategoriesToShopping(@PathVariable long idShopping) { return shoppingManagerService.findCategoriesToShopping(idShopping); } @GetMapping("/findCategories") List<CategoryDto> findCategories() { return shoppingManagerService.findCategories(); } @GetMapping("/findProductsToCategory/{idCategory}") List<ProductDto> findProductsToCategory(@PathVariable long idCategory) { return shoppingManagerService.findProductsToCategory(idCategory); } @GetMapping("/findProducts") List<ProductDto> findProducts() { return shoppingManagerService.findProducts(); } }

Here, we are creating a controller class

UserController.java We'll inject this bean into the UserManagerService bean using @Autowired on the field definition: We need to add map requests with request mapping annotations e.g. @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping

src/main/java/com/shoppingapp/controller/UserController.java):



package com.shoppingapp.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.shoppingapp.dto.CartDto; import com.shoppingapp.dto.ShoppingDto; import com.shoppingapp.dto.UserDto; import com.shoppingapp.manager.service.UserManagerService; @RestController @RequestMapping("api") @CrossOrigin(origins = "*") public class UserController { @Autowired private UserManagerService userManagerService; @PostMapping("/addUser") UserDto addUser(@RequestBody UserDto userDto) { return userManagerService.addUser(userDto); } @PutMapping("/editUser/{idUSer}") UserDto editUser(@RequestBody UserDto userDto, @PathVariable long idUser) { return userManagerService.editUser(userDto, idUser); } @DeleteMapping("/deleteUser/{idUser}") void deleteUser(@PathVariable long idUser) { userManagerService.deleteUser(idUser); } @GetMapping("/findCartsToUser/{idUser}") List<CartDto> findCartsToUser(@PathVariable long idUser) { return userManagerService.findCartsToUser(idUser); } @GetMapping("/findUserById/{idUser}") UserDto findUserById(@PathVariable long idUser) { return userManagerService.findUserById(idUser); } @GetMapping("/findUserByUsername/{username}") UserDto findUserByUsername(@PathVariable String username) { return userManagerService.findUserByName(username); } @GetMapping("/findShoppingToUser/{idUser}") List<ShoppingDto> findShoppingToUser(@PathVariable long idUser) { return userManagerService.findShoppingsToUser(idUser); } }

ShoppingAppApplication

@SpringBootApplication and its use in a simple Spring Boot application. We use the @SpringBootApplication annotation in our Application or Main class to enable a host of features, e.g. Java-based Spring configuration, component scanning, and in particular for enabling Spring


src/main/java/com/shoppingapp/ShoppingAppApplication.java):



package com.shoppingapp; import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @ComponentScan @SpringBootApplication public class ShoppingAppApplication { public static void main(String[] args) { SpringApplication.run(ShoppingAppApplication.class, args); System.out.println("App started...."); } }

Conclusion

Now we have an overview of Spring Boot CRUD example when building a CRUD App.

We also take a look at client-server architecture for REST API using Spring Web MVC & Spring Data JPA, as well, we are gooing to continue with Angular 10 project structure for building a front-end app to make HTTP requests and consume responses.





Post a Comment

Previous Post Next Post


Follow us on facebook