skip to Main Content

I’m working on a spring boot ecommerce app that requires cloudinary to persist image and get using the url.

However, all effort to get this done has been proved abortive. The code is not throwing any error but its not persisting in the cloudinary page and the database. And the response is null.

This is a response for example. Meanwhile i expect a link in the form of String

{
  "productName": "Track suit",
  "price": 300,
  "productDescription": "XXL",
  "productImage1": "",
  "productImage2": "",
  "productImage3": ""
} 

This is my code

ENTITY

@Entity
public class Product {

    @Id
    @GeneratedValue(generator="system-uuid")

    @GenericGenerator(name="system-uuid", strategy = "uuid")
    private String id;

    @Column
    private String productName;

    @Column
    private double price;

    @Column
    private String productDescription;

    @Column(nullable = false)
    private String productImage1;

    @Column(nullable = true)
    private String productImage2;

    @Column(nullable = true)
    private String productImage3;

    private LocalDateTime createdDate;

    private LocalDateTime updatedDate;

    @ManyToOne
    @JoinColumn(name = "admin_id")
    private Admin admin;

    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;

    @ManyToOne
    @JoinColumn(name = "users_entity_id")
    private UsersEntity usersEntity;
}

REQUEST DTO

@Data

public class UploadProductRequestDto {
    private String productName;
    private double price;
    private String productDescription;
    private MultipartFile productImage1;
    private MultipartFile productImage2;
    private MultipartFile productImage3;
}

RESPONSE DTO

@Data
public class UploadProductResponseDto {

    private String productName;
    private double price;
    private String productDescription;
    private String productImage1;
    private String productImage2;
    private String productImage3;

}

REPOSITORY

public interface ProductRepository extends JpaRepository<Product,String> {
    Optional<Product> findByProductName(String productName);
}

SERVICE

public interface ProductService {
 UploadProductResponseDto uploadProducts(UploadProductRequestDto uploadProductRequestDto, String categoryName) throws AuthorizationException, GeneralServiceException, ImageUploadException;
}

SERVICEIMPL

@Slf4j
@Service

public class ProductServiceImpl implements ProductService {

    @Autowired
    CloudStorageService cloudStorageService;

    @Autowired
    AdminRepository adminRepository;

    @Autowired
    CategoryRepository categoryRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    UserPrincipalService userPrincipalService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    ProductRepository productRepository;

    @Override
    public UploadProductResponseDto uploadProducts(UploadProductRequestDto uploadProductRequestDto, StringcategoryName) throws AuthorizationException, GeneralServiceException, ImageUploadException {

        Optional<Category> checkCategory = categoryRepository.findByCategoryName(categoryName);
        if (checkCategory.isEmpty()){
            throw new AuthorizationException(CATEGORY_NOT_RECOGNIZED);
        }

        Product product = new Product();
        product=mapAdminRequestDtoToProduct(uploadProductRequestDto,product);
        productRepository.save(product);
        UploadProductResponseDto adminUploadProductResponseDto = packageAdminProductUploadResponseDTO(product);
        return adminUploadProductResponseDto;
    }

    private UploadProductResponseDto packageAdminProductUploadResponseDTO(Product product){
        UploadProductResponseDto uploadProductResponseDto=new UploadProductResponseDto();
        modelMapper.map(product,uploadProductResponseDto);
        return uploadProductResponseDto;

    }

    private Product mapAdminRequestDtoToProduct(UploadProductRequestDto uploadProductRequestDto,Product product) throws ImageUploadException {

        modelMapper.map(uploadProductRequestDto,product);
        product=uploadProductImagesToCloudinaryAndSaveUrl(uploadProductRequestDto,product);
        product.setId("Product "+ IdGenerator.generateId());
        return product;

    }


    private Product uploadProductImagesToCloudinaryAndSaveUrl(UploadProductRequestDto uploadProductRequestDto,Product product) throws ImageUploadException {
       product.setProductImage1(imageUrlFromCloudinary(uploadProductRequestDto.getProductImage1()));
       product.setProductImage2(imageUrlFromCloudinary(uploadProductRequestDto.getProductImage2()));
       product.setProductImage3(imageUrlFromCloudinary(uploadProductRequestDto.getProductImage3()));

       return product;
    }


    private String imageUrlFromCloudinary(MultipartFile image) throws ImageUploadException {

        String imageUrl="";

        if(image!=null && !image.isEmpty()){
            Map<Object,Object> params=new HashMap<>();
            params.put("public_id","E&L/"+extractFileName(image.getName()));
            params.put("overwrite",true);
            try{
                Map<?,?> uploadResult = cloudStorageService.uploadImage(image,params);
                imageUrl= String.valueOf(uploadResult.get("url"));
            }catch (IOException e){
                e.printStackTrace();
                throw new ImageUploadException("Error uploading images,vehicle upload failed");
            }
        }
        return imageUrl;
    }

    private String extractFileName(String fileName){
        return fileName.split("\.")[0];
    }
}

Controller

@Slf4j
@RestController
@RequestMapping(ApiRoutes.ENMASSE)
public class ProductController {

    @Autowired
    ProductService productService;

    @PostMapping("/upload-product/categoryName")
    public ResponseEntity<?> UploadProduct(@ModelAttribute UploadProductRequestDto UploadProductRequestDto,@RequestParam String categoryName){

        try{
            return new ResponseEntity<>
(productService.uploadProducts(UploadProductRequestDto,categoryName), HttpStatus.OK);
        }catch (Exception exception){
            return new ResponseEntity<>(exception.getMessage(),HttpStatus.BAD_REQUEST);
        }
    }
}

CLOUD

cloudConfig

@Component
@Data

 public class CloudinaryConfig {

 @Value("${CLOUD_NAME}")
 private String cloudName;

 @Value("${API_KEY}")
 private String apikey;

 @Value("${API_SECRET}")
 private String secretKey;

}

CloudConfiguration

@Component

public class CloudinaryConfiguration {

@Autowired
CloudinaryConfig cloudinaryConfig;

@Bean
public Cloudinary getCloudinaryConfig(){
    return new Cloudinary(ObjectUtils.asMap("cloud_name",cloudinaryConfig.getCloudName(),
            "api_key",cloudinaryConfig.getApikey(),"api_secret",cloudinaryConfig.getSecretKey()));
}

}

CloudinaryStorageServiceImpl

 @Service

 public class CloudinaryStorageServiceImpl implements CloudStorageService{

@Autowired
Cloudinary cloudinary;

@Override

public Map<?, ?> uploadImage(File file, Map<?, ?> imageProperties) throws IOException {
    return cloudinary.uploader().upload(file,imageProperties);
}

@Override

public Map<?, ?> uploadImage(MultipartFile multipartFile, Map<?, ?> imageProperties) throws IOException {
    return cloudinary.uploader().upload(multipartFile.getBytes(),imageProperties);
}
}

CloudStorageService

public interface CloudStorageService {

Map<?,?> uploadImage(File file, Map<?,?> imageProperties) throws IOException;

Map<?,?> uploadImage(MultipartFile multipartFile, Map<?, ?> imageProperties) throws IOException;
}

2

Answers


  1. Chosen as BEST ANSWER

    It happens that there is nothing wrong with my code. The issue is that it has to be coupled with the frontend so the image tag can render it. Thank you.


    1. You didn’t include the implementation of cloudStorageService.uploadImage(?,?) in the code you pasted here.
    2. Cloudinary’s Java implementation requires you pass in the multipart file in bytes. I do not know if you have that since your upload method isn’t here.

    Maybe refer to the simple implementation here

    PS: You can clone the repo to see the implementation of the upload method in the CloudinaryServiceImpl.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search