Skip to content

Commit

Permalink
product image upload and download
Browse files Browse the repository at this point in the history
  • Loading branch information
casyazmon committed Aug 10, 2023
1 parent 8d98258 commit fc88b19
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.kasina.automobileapi.controller;

import com.kasina.automobileapi.model.ImageModel;
import com.kasina.automobileapi.model.Product;
import com.kasina.automobileapi.dto.ProductDto;
import com.kasina.automobileapi.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -41,6 +45,18 @@ public ResponseEntity<?> getProductByCategory(@PathVariable Long id) {
return new ResponseEntity<>(product, HttpStatus.OK);
}

/* @PostMapping(value = "/add-products", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<List<Product>> addMultipleProducts(@RequestBody List<ProductDto> productDtos,
@RequestPart("imageFile")MultipartFile[] imageFile) {
try{
List<Product> addedProducts = productService.addMultipleProducts(productDtos, imageFile);
return new ResponseEntity<>(addedProducts, HttpStatus.CREATED);
}catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}*/

@PostMapping
public ResponseEntity<?> addProduct(@RequestBody ProductDto productDto){
Expand All @@ -60,4 +76,5 @@ public ResponseEntity<?> deleteProduct(@PathVariable Long id) {
return ResponseEntity.ok("Product deleted successfully");
}


}
3 changes: 2 additions & 1 deletion src/main/java/com/kasina/automobileapi/dto/ProductDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kasina.automobileapi.dto;

import com.kasina.automobileapi.model.ImageModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,6 +16,6 @@ public class ProductDto {
private String description;
private String shortDescription;
private BigDecimal price;
private String image;
private List<String> categories;
private String image;
}
35 changes: 35 additions & 0 deletions src/main/java/com/kasina/automobileapi/model/ImageModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.kasina.automobileapi.model;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.math.BigDecimal;
import java.time.Instant;

@Data
@AllArgsConstructor
@RequiredArgsConstructor
@Entity
@Table(name = "images")
public class ImageModel {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String type;
@Lob
private byte[] picByte;


@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product;

public ImageModel(String originalFilename, String contentType, byte[] bytes) {
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/kasina/automobileapi/model/Product.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Data
Expand All @@ -27,6 +29,9 @@ public class Product {
private BigDecimal price;
private String image;

/*@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ImageModel> images = new ArrayList<>();*/

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
@JsonIgnore
Expand Down Expand Up @@ -55,4 +60,5 @@ public void removeCategory(Category category) {
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.kasina.automobileapi.repository;

import com.kasina.automobileapi.model.ImageModel;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ImageModelRepository extends JpaRepository<ImageModel, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
public class CategoryService {
private final CategoryRepository categoryRepository;



// Create a new Category
public Category createCategory(Category Category) {
return categoryRepository.save(Category);
public Category createCategory(Category category) {
Optional<Category> defaultCategoryOpt = categoryRepository.findByName(category.getName());
return defaultCategoryOpt.orElseGet(() -> categoryRepository.save(category));
}

// Get all Categories
Expand All @@ -29,7 +28,6 @@ public List<Category> getAllCategories() {
}

// Get a Category by ID

public Category getCategoryById(Long userId) {
return categoryRepository.findById(userId)
.orElseThrow(() -> new NoSuchElementException("Category not found with ID: " + userId));
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/com/kasina/automobileapi/service/ProductService.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
package com.kasina.automobileapi.service;

import com.kasina.automobileapi.model.Category;
import com.kasina.automobileapi.model.ImageModel;
import com.kasina.automobileapi.model.Product;
import com.kasina.automobileapi.dto.ProductDto;
import com.kasina.automobileapi.dto.UrlErrorResponseDto;
import com.kasina.automobileapi.model.User;
import com.kasina.automobileapi.repository.ImageModelRepository;
import com.kasina.automobileapi.repository.ProductRepository;
import com.kasina.automobileapi.repository.UserRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@Service
@RequiredArgsConstructor
public class ProductService {
@Autowired
private final ProductRepository productRepository;

@Autowired
private final ImageModelRepository imageModelRepository;
@Autowired
private final UserService userService;
@Autowired
private final CategoryService categoryService;
@Value("${upload.path}")
private String uploadPath;


public Product createProduct(ProductDto productDto) {

Expand All @@ -48,6 +64,34 @@ public Product createProduct(ProductDto productDto) {
return productRepository.save(product);
}

// add multiple products at once

/*public List<Product> addMultipleProducts(List<ProductDto> productDtos, MultipartFile[] imageFiles) throws IOException {
User currentUser = userService.getCurrentUser();
List<Product> addedProducts = new ArrayList<>();
List<ImageModel> images = uploadImage(imageFiles);
for (ProductDto productDto : productDtos) {
Set<Category> categories = new HashSet<>();
Product product = new Product();
product.setName(productDto.getName());
product.setDescription(productDto.getDescription());
product.setShortDescription(productDto.getShortDescription());
product.setPrice(productDto.getPrice());
product.setUser(currentUser);
// product.setProductImages(images);
for (String categoryName : productDto.getCategories()) {
Category category = categoryService.getDefaultCategory(categoryName);
categories.add(category);
}
product.setCategories(categories);
addedProducts.add(product);
}
return productRepository.saveAll(addedProducts);
}*/


public Product updateProduct(ProductDto productDto, Long id){
Set<Category> categories = new HashSet<>();
User currentUser = userService.getCurrentUser();
Expand Down Expand Up @@ -97,4 +141,35 @@ public Optional<List<Product>> findProductByCategory(Long catId) {
Category category = categoryService.getCategoryById(catId);
return productRepository.findByCategories(category);
}

public List<ImageModel> uploadImage(MultipartFile[] imageFiles) throws IOException {

Set<ImageModel> newImages = new HashSet<>();
for(MultipartFile imageFile: imageFiles){
ImageModel file = new ImageModel(
imageFile.getOriginalFilename(),
imageFile.getContentType(),
imageFile.getBytes()
);
newImages.add(file);
}
return imageModelRepository.saveAll(newImages);
}

public ImageModel saveImage(MultipartFile file) throws IOException {
String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
ImageModel image = new ImageModel(fileName, file.getContentType(), file.getBytes());
return imageModelRepository.save(image);
}

public String storeImage(MultipartFile file) {
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
Path filePath = Paths.get(uploadPath + fileName);
try {
Files.write(filePath, file.getBytes());
} catch (IOException e) {
throw new RuntimeException("Failed to store image: " + e.getMessage());
}
return fileName;
}
}
5 changes: 5 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ app.jwt.secret=404E635266556A586E3272357538782F413F4428472B4B6250645367566B5970
app.jwt.expiration =

logging.level.org.springframework.security=TRACE
upload.path=/path/to/your/image/upload/directory/

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

0 comments on commit fc88b19

Please sign in to comment.