Code with Spring Boot 3
Sr No. | Topic |
---|---|
0 | Project Structure 1 |
1 | Project Structure 2 |
2 | Project Structure 3 |
src
└── main
├── java
│ └── com
│ └── example
│ ├──config
│ ├──controllers
│ ├──models
│ ├──repo
│ ├──service
│ └──App.java
└── resources
└── application.properties
Path : src/main/java/com/sp/product/Ecommerce/models
package com.sp.product.Ecommerce.models;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class Cart {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer cartId;
private Double totalAmount;
@OneToOne(fetch = FetchType.EAGER)
@JsonIgnore
private User user;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER, mappedBy = "cart")
private List<CartProduct> cartProducts;
public Cart() {
super();
}
public Cart(Integer cartId, Double totalAmount, User user, List<CartProduct> cartProducts) {
super();
this.cartId = cartId;
this.totalAmount = totalAmount;
this.user = user;
this.cartProducts = cartProducts;
}
public Integer getCartId() {
return cartId;
}
public void setCartId(Integer cartId) {
this.cartId = cartId;
}
public Double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<CartProduct> getCartProducts() {
return cartProducts;
}
public void setCartProducts(List<CartProduct> cartProducts) {
this.cartProducts = cartProducts;
}
@Override
public String toString() {
return "Cart [cartId=" + cartId + ", totalAmount=" + totalAmount + ", user=" + user.getUserId()
+ ", cartProducts=" + cartProducts + "]";
}
public void updateTotalAmount(Double price) {
this.totalAmount += price;
}
}
package com.sp.product.Ecommerce.models;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "cart_id", "product_id" }))
@Entity
public class CartProduct {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer cpId;
@ManyToOne()
@JoinColumn(name = "cart_id", referencedColumnName = "cartId")
@JsonIgnore
private Cart cart;
@ManyToOne()
@JoinColumn(name = "product_id", referencedColumnName = "productId")
private Product product;
private Integer quantity = 1;
public CartProduct() {
super();
}
public CartProduct(Cart cart, Product product, Integer quantity) {
super();
this.cart = cart;
this.product = product;
this.quantity = quantity;
}
public Integer getCpId() {
return cpId;
}
public void setCpId(Integer cpId) {
this.cpId = cpId;
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return "CartProduct [cpId=" + cpId + ", cart=" + cart.getCartId() + ", product=" + product.getProductId()
+ ", quantity=" + quantity + "]";
}
}
package com.sp.product.Ecommerce.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class Category {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@JsonIgnore
private Integer categoryId;
@Column(unique = true)
private String categoryName;
public Category() {
super();
}
public Category(String categoryName) {
super();
this.categoryName = categoryName;
}
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
@Override
public String toString() {
return "Category [categoryId=" + categoryId + ", categoryName=" + categoryName + "]";
}
}
package com.sp.product.Ecommerce.models;
public class JWTrequest {
String username;
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;
}
String password;
public JWTrequest(String username, String password) {
super();
this.username = username;
this.password = password;
}
public JWTrequest() {
super();
}
}
package com.sp.product.Ecommerce.models;
public class JWTresponse {
String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public JWTresponse(String token) {
super();
this.token = token;
}
public JWTresponse() {
super();
}
}
package com.sp.product.Ecommerce.models;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class Product {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer productId;
private String productName;
private Double price;
@ManyToOne()
@JoinColumn(name = "seller_id", referencedColumnName = "userId", updatable = false)
@JsonIgnore
private User seller;
@ManyToOne()
@JoinColumn(name = "category_id", referencedColumnName = "categoryId")
private Category category;
public Product() {
super();
}
public Product(Integer productId, String productName, Double price, User seller, Category category) {
super();
this.productId = productId;
this.productName = productName;
this.price = price;
this.seller = seller;
this.category = category;
}
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public User getSeller() {
return seller;
}
public void setSeller(User seller) {
this.seller = seller;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
@Override
public String toString() {
return "Product [productId=" + 0 + ", productName=" + productName + ", price=" + price + ", seller="
+ seller.getUserId() + ", category=" + category + "]";
}
}
package com.sp.product.Ecommerce.models;
import org.springframework.security.core.GrantedAuthority;
public enum Role {
CONSUMER, SELLER;
}
class RoleGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = -3408298481881657796L;
String role;
public RoleGrantedAuthority(String role) {
this.role = role;
}
@Override
public String getAuthority() {
return this.role;
}
}
package com.sp.product.Ecommerce.models;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
@Entity
public class User implements UserDetails {
private static final long serialVersionUID = 5536306799835655715L;
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer userId;
@Column(unique = true)
private String username;
private String password;
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<Role> roles;
public User() {
super();
}
public User(String username, String password, Set<Role> roles) {
super();
this.username = username;
this.password = password;
this.roles = roles;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
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 Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "User [userId=" + userId + ", username=" + username + ", password=" + password + ", roles=" + roles
+ "]";
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.roles.stream().map(r -> new RoleGrantedAuthority(r.name())).collect(Collectors.toList());
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Path : src/main/java/com/sp/product/Ecommerce/repo
package com.sp.product.Ecommerce.repo;
import java.util.Optional;
import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sp.product.Ecommerce.models.CartProduct;
@Repository
public interface CartProductRepo extends JpaRepository<CartProduct, Integer> {
Optional<CartProduct> findByCartUserUserIdAndProductProductId(Integer userId, Integer productId);
@Transactional
void deleteByCartUserUserIdAndProductProductId(Integer userId, Integer productId);
}
package com.sp.product.Ecommerce.repo;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sp.product.Ecommerce.models.Cart;
@Repository
public interface CartRepo extends JpaRepository<Cart, Integer> {
Optional<Cart> findByUserUsername(String username);
}
package com.sp.product.Ecommerce.repo;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sp.product.Ecommerce.models.Category;
@Repository
public interface CategoryRepo extends JpaRepository<Category, Integer> {
Optional<Category> findByCategoryName(String category);
}
package com.sp.product.Ecommerce.repo;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sp.product.Ecommerce.models.Product;
@Repository
public interface ProductRepo extends JpaRepository<Product, Integer> {
List<Product> findByProductNameContainingIgnoreCaseOrCategoryCategoryNameContainingIgnoreCase(String productName,
String categoryName);
List<Product> findBySellerUserId(Integer sellerId);
Optional<Product> findBySellerUserIdAndProductId(Integer sellerId, Integer productId);
}
package com.sp.product.Ecommerce.repo;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sp.product.Ecommerce.models.User;
@Repository
public interface UserRepo extends JpaRepository<User, Integer> {
Optional<User> findByUsername(String username);
}
Path : src/main/java/com/sp/product/Ecommerce/service
package com.sp.product.Ecommerce.service;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.sp.product.Ecommerce.models.User;
import com.sp.product.Ecommerce.repo.UserRepo;
@Service
public class UserAuthService implements UserDetailsService {
@Autowired
private UserRepo userRepo;
public User loadUserByUserID(Integer id) {
Optional<User> user = userRepo.findById(id);
if (user.isPresent())
return user.get();
else
throw new UsernameNotFoundException("User ID not found");
}
@Override
public User loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<User> user = userRepo.findByUsername(username);
if (user.isPresent())
return user.get();
else
throw new UsernameNotFoundException("User ID not found");
}
}
Path : src/main/java/com/sp/product/Ecommerce/controllers
package com.sp.product.Ecommerce.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sp.product.Ecommerce.config.JwtUtil;
import com.sp.product.Ecommerce.models.Cart;
import com.sp.product.Ecommerce.models.CartProduct;
import com.sp.product.Ecommerce.models.Product;
import com.sp.product.Ecommerce.models.User;
import com.sp.product.Ecommerce.repo.CartProductRepo;
import com.sp.product.Ecommerce.repo.CartRepo;
import com.sp.product.Ecommerce.repo.CategoryRepo;
import com.sp.product.Ecommerce.repo.ProductRepo;
import com.sp.product.Ecommerce.repo.UserRepo;
@RestController
@RequestMapping("/api/auth/consumer")
public class ConsumerController {
@Autowired
CartRepo cartRepo;
@Autowired
CategoryRepo categoryRepo;
@Autowired
UserRepo userRepo;
@Autowired
ProductRepo productRepo;
@Autowired
CartProductRepo cpRepo;
@Autowired
private JwtUtil jwtUtil;
@GetMapping("/cart")
public ResponseEntity<Object> getCart(@RequestHeader("JWT") String jwt) {
String username = jwtUtil.extractUsername(jwt);
System.out.println(cartRepo.findByUserUsername(username).toString());
return ResponseEntity.ok(cartRepo.findByUserUsername(username));
}
@PostMapping("/cart")
public ResponseEntity<Object> postCart(@RequestHeader("JWT") String jwt, @RequestBody Product product) {
String username = jwtUtil.extractUsername(jwt);
Cart cart = cartRepo.findByUserUsername(username).get();
Product prod = productRepo.findById(product.getProductId()).get();
if (!cart.getCartProducts().stream().anyMatch(n -> n.getProduct().equals(prod))) {
CartProduct cp = new CartProduct();
cp.setCart(cart);
cp.setProduct(prod);
cp.setQuantity(1);
cart.getCartProducts().add(cp);
cart.updateTotalAmount(prod.getPrice() * cp.getQuantity());
cartRepo.save(cart);
return ResponseEntity.ok(cart);
} else {
return ResponseEntity.status(409).build();
}
}
@PutMapping("/cart")
public ResponseEntity<Object> putCart(@RequestHeader("JWT") String jwt, @RequestBody CartProduct cartProd) {
String username = jwtUtil.extractUsername(jwt);
User user = userRepo.findByUsername(username).orElse(null);
Cart cart = cartRepo.findByUserUsername(username).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body("No user found");
}
Product prod = productRepo.findById(cartProd.getProduct().getProductId()).orElse(null);
if (prod == null) {
return ResponseEntity.badRequest().body("No product found");
}
CartProduct cp = cart.getCartProducts().stream().filter(n -> n.getProduct().equals(prod)).findFirst()
.orElse(null);
if (cp == null) {
if (cartProd.getQuantity() > 0) {
cp = new CartProduct();
cp.setProduct(prod);
cp.setQuantity(cartProd.getQuantity());
cart.updateTotalAmount(prod.getPrice() * cartProd.getQuantity());
cp.setCart(cart);
cart.getCartProducts().add(cp);
}
} else {
if (cartProd.getQuantity() == 0) {
cart.getCartProducts().remove(cp);
System.out.println(prod.getPrice() + "abc " + cartProd.getQuantity());
cart.updateTotalAmount(-prod.getPrice() * cp.getQuantity());
cpRepo.delete(cp);
} else {
cart.updateTotalAmount(prod.getPrice() * (cartProd.getQuantity() - cp.getQuantity()));
cart.getCartProducts().get(cart.getCartProducts().indexOf(cp)).setQuantity(cartProd.getQuantity());
}
}
cartRepo.saveAndFlush(cart);
return ResponseEntity.ok(cart);
}
@DeleteMapping("/cart")
public ResponseEntity<Object> deleteCart(@RequestHeader("JWT") String jwt, @RequestBody Product prod) {
String username = jwtUtil.extractUsername(jwt);
Cart cart = cartRepo.findByUserUsername(username).orElse(null);
if (cart == null) {
return ResponseEntity.badRequest().body("No cart found");
}
CartProduct cp = cart.getCartProducts().stream()
.filter(n -> n.getProduct().getProductId().equals(prod.getProductId())).findFirst().orElse(null);
if (cp == null) {
return ResponseEntity.badRequest().body("No product found");
}
cart.getCartProducts().remove(cp);
cart.updateTotalAmount(-cp.getProduct().getPrice() * cp.getQuantity());
cpRepo.delete(cp);
cartRepo.save(cart);
return ResponseEntity.ok(cart);
}
}
package com.sp.product.Ecommerce.controllers;
public class MyExceptionHandler {
}
package com.sp.product.Ecommerce.controllers;
import java.util.List;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.sp.product.Ecommerce.config.JwtUtil;
import com.sp.product.Ecommerce.models.JWTrequest;
import com.sp.product.Ecommerce.models.Product;
import com.sp.product.Ecommerce.repo.ProductRepo;
@RestController
@RequestMapping("/api/public")
public class PublicController {
@Autowired
AuthenticationManager auth;
@Autowired
JwtUtil jwtUtil;
@Autowired
ProductRepo prodRepo;
@GetMapping("/product/search")
public List<Product> getProducts(@RequestParam("keyword") String keyword) {
return prodRepo.findByProductNameContainingIgnoreCaseOrCategoryCategoryNameContainingIgnoreCase(keyword, keyword);
}
@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody JWTrequest request) {
try {
auth.authenticate(new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
String token = jwtUtil.generateToken(request.getUsername());
return ResponseEntity.ok(token);
}
}
package com.sp.product.Ecommerce.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.sp.product.Ecommerce.config.JwtUtil;
import com.sp.product.Ecommerce.models.Category;
import com.sp.product.Ecommerce.models.Product;
import com.sp.product.Ecommerce.models.User;
import com.sp.product.Ecommerce.repo.CartProductRepo;
import com.sp.product.Ecommerce.repo.CartRepo;
import com.sp.product.Ecommerce.repo.CategoryRepo;
import com.sp.product.Ecommerce.repo.ProductRepo;
import com.sp.product.Ecommerce.repo.UserRepo;
@RestController
@RequestMapping("/api/auth/seller")
public class SellerController {
@Autowired
ProductRepo productRepo;
@Autowired
CartRepo cartRepo;
@Autowired
CategoryRepo categoryRepo;
@Autowired
UserRepo userRepo;
@Autowired
CartProductRepo cpRepo;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/product")
public ResponseEntity<Object> postProduct(@RequestHeader("JWT") String jwt, @RequestBody Product product) {
User user = userRepo.findByUsername(jwtUtil.extractUsername(jwt)).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body("No user found");
}
Category category = categoryRepo.findByCategoryName(product.getCategory().getCategoryName()).get();
if (category == null) {
return ResponseEntity.badRequest().body("No user found");
}
product.setSeller(user);
product.setCategory(category);
productRepo.saveAndFlush(product);
return ResponseEntity.ok(product);
// return ResponseEntity.status(HttpStatus.CREATED).body("http://localhost/api/auth/seller/product/" + product.getProductId());
}
@GetMapping("/product")
public ResponseEntity<Object> getAllProducts(@RequestHeader("JWT") String jwt) {
String username = jwtUtil.extractUsername(jwt);
User user = userRepo.findByUsername(username).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body("No user found");
}
List<Product> list = productRepo.findBySellerUserId(user.getUserId());
return ResponseEntity.ok(list);
}
@GetMapping("/product/{productId}")
public ResponseEntity<Object> getProduct(@RequestHeader("JWT") String jwt, @PathVariable Integer productId) {
String username = jwtUtil.extractUsername(jwt);
User user = userRepo.findByUsername(username).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body("No user found");
}
Product prod = productRepo.findBySellerUserIdAndProductId(user.getUserId(), productId).orElse(null);
return ResponseEntity.ok(prod);
}
@PutMapping("/product")
public ResponseEntity<Object> putProduct(@RequestHeader("JWT") String jwt, @RequestBody Product product) {
String username = jwtUtil.extractUsername(jwt);
User user = userRepo.findByUsername(username).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body("No user found");
}
Product prod = productRepo.findBySellerUserIdAndProductId(user.getUserId(), product.getProductId())
.orElse(null);
Category category = categoryRepo.findByCategoryName(product.getCategory().getCategoryName()).get();
if (prod == null) {
return ResponseEntity.badRequest().body("No product found");
}
if (category == null) {
return ResponseEntity.badRequest().body("No Category found");
}
prod.setProductName(product.getProductName());
prod.setPrice(product.getPrice());
prod.setCategory(category);
productRepo.saveAndFlush(prod);
return ResponseEntity.ok(prod);
}
@DeleteMapping("/product/{productId}")
public ResponseEntity<Product> deleteProduct(@RequestHeader("JWT") String jwt, @PathVariable Integer productId) {
String username = jwtUtil.extractUsername(jwt);
User user = userRepo.findByUsername(username).orElse(null);
if (user == null) {
return ResponseEntity.badRequest().body(null);
}
System.out.println(productId);
Product product = productRepo.findBySellerUserIdAndProductId(user.getUserId(), productId).orElse(null);
if (product == null) {
return ResponseEntity.status(404).body(null);
}
productRepo.delete(product);
return ResponseEntity.ok(product);
}
}
Path : src/main/java/com/sp/product/Ecommerce/config
package com.sp.product.Ecommerce.config;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component
public class ApiAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(401, "unautherized");
}
}
package com.sp.product.Ecommerce.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.sp.product.Ecommerce.service.UserAuthService;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class ApiSecurityConfig {
@Autowired
JwtAuthenticationFilter filter;
@Autowired
ApiAuthenticationEntryPoint entryPoint;
@Autowired
UserAuthService userDetails;
// @Override
// public void configure(WebSecurity web) throws Exception {
//
// }
@Bean
public PasswordEncoder getPasswordEndcoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.exceptionHandling(exp -> exp.authenticationEntryPoint(entryPoint))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/auth/consumer/**").hasAnyAuthority("CONSUMER")
.requestMatchers("/api/auth/seller/**").hasAnyAuthority("SELLER")
.anyRequest()
.authenticated());
http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
// @Bean
// public RegistrationBean jwtAuthFilterRegister(JwtAuthenticationFilter filter) {
// return null;
// }
}
package com.sp.product.Ecommerce.config;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.sp.product.Ecommerce.service.UserAuthService;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
JwtUtil jwtUtil;
@Autowired
UserAuthService userDetails;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String header = request.getHeader("Authorization");
String token = null, username = null;
UserDetails user = null;
if (header != null && header.startsWith("Bearer")) {
token = header.substring(7);
username = jwtUtil.extractUsername(token);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
user = userDetails.loadUserByUsername(username);
if (user != null && jwtUtil.validateToken(token, user)) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null,
user.getAuthorities());
auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
filterChain.doFilter(request, response);
}
}
package com.sp.product.Ecommerce.config;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import com.sp.product.Ecommerce.models.User;
import com.sp.product.Ecommerce.service.UserAuthService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@Component
public class JwtUtil {
@Autowired
UserAuthService userDetails;
public User getUser(final String token) {
String username = extractUsername(token);
return userDetails.loadUserByUsername(username);
}
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 2))
.signWith(SignatureAlgorithm.HS256, "secret").compact();
}
public boolean validateToken(final String token,UserDetails user) {
return user.getUsername().equals(extractUsername(token)) && extractExpiration(token).after(new Date());
}
public Claims extractClaims(String token) {
return Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getBody();
}
public Date extractExpiration(final String token) {
return extractClaims(token).getExpiration();
}
public String extractUsername(final String token) {
return extractClaims(token).getSubject();
}
}
src/main/resources/application.properties
spring.application.name=Ecommerce
server.port=8000
spring.h2.console.path=/h2
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.initialization-mode=always
jwt.secret=secretkey
jwt.token.validity=900000
src/main/resources/data.sql
INSERT INTO category ("CATEGORY_NAME") VALUES ('Fashion');
INSERT INTO user ("USERNAME", "PASSWORD") VALUES ('John', 'pass_word');
INSERT INTO cart ("TOTAL_AMOUNT", "USER_USER_ID" ) VALUES (20, 1);
INSERT INTO USER_ROLE ("USER_ID", "ROLES") VALUES (1, 'CONSUMER');
INSERT INTO PRODUCT ("PRICE", "PRODUCT_NAME", "CATEGORY_ID", "SELLER_ID") VALUES (29190, 'Apple MacBook', 2, 3);
INSERT INTO CART_PRODUCT ("CART_ID", "PRODUCT_ID", "QUANTITY") VALUES (1, 2, 2);
When developing a Spring Boot application, it’s essential to understand the flow and the order in which files are typically created and referenced. Below is a step-by-step guide to creating the necessary files for a CRUD REST API, explaining how each file is referenced in the overall architecture.
Model: Start by defining the data structure of your entities. The Employee
class is created first as it defines what data you are working with.
Repository: Next, create the repository interface. The repository will manage the CRUD operations for the Employee
model.
Service: Create the service layer. The service contains the business logic and interacts with the repository to perform CRUD operations.
Controller: Create the controller that will handle HTTP requests and responses. The controller will use the service to get the necessary data and return it to the client.
Configuration: Finally, configure security settings if needed. This step can be done at any time after the basic CRUD operations are functional.
Each layer references the previous ones: