Rumah  >  Artikel  >  Java  >  Menyimpan imej untuk apl UGC anda menggunakan Spring Boot dan iDrive E3

Menyimpan imej untuk apl UGC anda menggunakan Spring Boot dan iDrive E3

DDD
DDDasal
2024-10-14 06:11:29899semak imbas

Helo dunia!

Ini adalah artikel kedua tentang pengalaman saya di Makers membina klon rangkaian sosial. Pautan ke artikel pertama - https://dev.to/olnov/working-with-http-requests-in-spring-boot-5el0. Yang semasa dikhaskan untuk menyimpan imej untuk profil pengguna.

Langkah #1. Perancangan.

Sebagai sebahagian daripada MVP kami, kami memutuskan untuk melaksanakan cerita pengguna berikut:

Sebagai pengguna,

Saya mahu mengemas kini profil saya untuk memasukkan foto saya,

Supaya pengguna lain dapat mencari saya dengan mudah dalam apl

Kami juga bersetuju dengan keperluan tidak berfungsi.

  • Fail imej ialah PNG atau JPG sahaja.
  • Saiz fail tidak boleh melebihi 1 MB.

Langkah #2. Analisis dan Reka Bentuk.

Kami datang dengan pilihan yang berbeza untuk tempat menyimpan imej - folder pelayan jauh, pangkalan data dan storan objek. Walaupun aplikasi kami tidak dimuatkan dengan tinggi, kami memutuskan untuk menggunakan S3 sebagai penyelesaian yang paling sesuai untuk sistem teragih. (P.S. dan saya mempunyai langganan iDrive e2 sedia ada daripada projek sebelumnya).

Dalam Pangkalan Data, hanya terdapat pautan ke URL awam storan iDrive.

Berikut ialah rajah DB:

Storing images for your UGC app using Spring Boot and iDrive E3

Rajah apl peringkat tinggi:

Storing images for your UGC app using Spring Boot and iDrive E3

Langkah #3. Bina.

Bahagian hujung belakang memerlukan perkara berikut untuk dilengkapkan:

  • Tambahkan AWS SDK pada projek.
  • Laksanakan Perkhidmatan Imej untuk berfungsi dengan penyepaduan luaran.
  • Laksanakan Pengawal Imej untuk meletakkan imej ke dalam baldi menggunakan Perkhidmatan Imej dan simpan rekod yang sepadan dalam DB.

Dalam pom.xml saya menambah yang berikut:

       <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <version>2.28.18</version>
        </dependency>

Kelas Perkhidmatan Imej:

package com.makersacademy.acebook.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

import java.io.InputStream;
import java.net.URI;
import java.util.UUID;

@Service
public class ImageService {

    private final S3Client s3Client;

    @Value("${idrive.e2.bucket-name}")
    private String bucketName;

    @Value("${idrive.e2.endpoint}")
    private String endpoint;

    @Value("${idrive.e2.public_endpoint}")
    private String public_endpoint;

    public ImageService(@Value("${idrive.e2.access-key}") String accessKey,
                        @Value("${idrive.e2.secret-key}") String secretKey,
                        @Value("${idrive.e2.endpoint}") String endpoint) {
        AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
        this.s3Client = S3Client.builder()
                .credentialsProvider(StaticCredentialsProvider.create(credentials))
                .endpointOverride(URI.create(endpoint))
                .region(Region.AWS_GLOBAL) // I dind't see exact instructions from iDrive, so I set this parameter to AWS_GLOBAL
                .build();
    }

    public String uploadImage(InputStream imageStream, long contentLength, String contentType) {
        String key = "media/" + UUID.randomUUID();

        PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .contentType(contentType)
                .contentLength(contentLength) // Specify the content length
                .build();

        s3Client.putObject(putObjectRequest, software.amazon.awssdk.core.sync.RequestBody.fromInputStream(imageStream, contentLength));

        // Return the image URL
        return public_endpoint + "/" + bucketName + "/" + key;
    }
}

Pembolehubah sambungan Idrive disimpan dalam fail application.properties:

#S3 storage settings
idrive.e2.access-key=${E2_ACCESS_KEY}
idrive.e2.secret-key=${E2_SECRET_KEY}
idrive.e2.endpoint=${E2_ENDPOINT}
idrive.e2.bucket-name=${E2_BUCKET_NAME}
idrive.e2.public_endpoint=${E2_PUBLIC_ENDPOINT}

Ok, sekarang Kelas Pengawal Imej:

package com.makersacademy.acebook.controller;

import com.makersacademy.acebook.model.Post;
import com.makersacademy.acebook.repository.PostRepository;
import com.makersacademy.acebook.service.ImageService;
import com.makersacademy.acebook.model.User;
import com.makersacademy.acebook.repository.UserRepository;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.RedirectView;

import java.io.IOException;

@Controller
public class ImageController {

    @Autowired
    private ImageService imageService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PostRepository postRepository;

    @PostMapping("/upload/{userId}")
    public RedirectView uploadImage(@PathVariable Long userId, @RequestParam("file") MultipartFile file) {
        try {
            // Check if the user exists
            User user = userRepository.findById(userId).orElseThrow(()->new RuntimeException("User not found"));

            // Upload image to IDrive e2 and get image URL
            String imageUrl = imageService.uploadImage(file.getInputStream(), file.getSize(), file.getContentType());

            // Save the image URL in the user's profile
            user.setUser_photo(imageUrl);
            userRepository.save(user);

            return new RedirectView("/media/"+userId);

        } catch (IOException e) {
            throw new RuntimeException("Error uploading file:"+e.getMessage());
        }
    }

    @PostMapping("/upload/post")
    public RedirectView uploadImageAsPost(@RequestParam("file") MultipartFile file, HttpSession session){
        try {
            Long userId = (Long) session.getAttribute("user_id");
            if (userId == null) {
                throw new RuntimeException("Not authorized");
            }

            String imageUrl = imageService.uploadImage(file.getInputStream(), file.getSize(), file.getContentType());
            User user = userRepository.findById(userId)
                    .orElseThrow(() -> new RuntimeException("User not found"));
            Post post = new Post(imageUrl,user,true);
            postRepository.save(post);
            return new RedirectView("/");
        } catch (IOException e) {
            throw new RuntimeException("Error uploading file:"+e.getMessage());
        }
    }
}

Di bahagian hadapan untuk memuat naik imej profil saya menambah yang berikut:

<div class="mb-3">
     <form id="image-form" th:action="@{/api/images/upload/{id}(id=${user.id})}" method="post"
                           enctype="multipart/form-data">
      <"formFile" class="form-label btn btn-primary">Upload Image</label>
      <input class="form-control" type="file" name="file" id="formFile" accept=".jpg,.jpeg,.png"
                           onchange="autoSubmitImage()" hidden/>
      </form>
 </div>

 <script th:inline="javascript">
    /*<![CDATA[*/
        const autoSubmitImage = ()=> {
          document.getElementById("image-form").submit();
        }
    /*]]>*/
</script>

Dan hasilnya.

Storing images for your UGC app using Spring Boot and iDrive E3

Ini dia.

Sola!

Atas ialah kandungan terperinci Menyimpan imej untuk apl UGC anda menggunakan Spring Boot dan iDrive E3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn