From 0487b32c37b66d0d4571d329dfa3714ba03b01ec Mon Sep 17 00:00:00 2001 From: Park MinJe Date: Sun, 20 Aug 2023 05:07:34 +0900 Subject: [PATCH 1/2] =?UTF-8?q?setting=20for=202.1.4=20=EC=95=BD=EB=AC=BC?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=A1=9C=20=EC=8B=9D=EB=B3=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /*TODO*/ 모델 서버 작동 후에 식별 요청 --- .../config/BaseResponseStatus.java | 2 + .../src/controller/MedicineController.java | 32 +++++++ .../src/dto/medicine/PillImageDto.java | 35 ++++++++ .../WhatIsMethIs/src/entity/PillImage.java | 53 +++++++++++ .../src/repository/PillImageRepository.java | 7 ++ .../src/service/PillImageService.java | 57 ++++++++++++ .../com/WhatIsMethIs/utils/FileHandler.java | 88 +++++++++++++++++++ 7 files changed, 274 insertions(+) create mode 100644 src/main/java/com/WhatIsMethIs/src/dto/medicine/PillImageDto.java create mode 100644 src/main/java/com/WhatIsMethIs/src/entity/PillImage.java create mode 100644 src/main/java/com/WhatIsMethIs/src/repository/PillImageRepository.java create mode 100644 src/main/java/com/WhatIsMethIs/src/service/PillImageService.java create mode 100644 src/main/java/com/WhatIsMethIs/utils/FileHandler.java diff --git a/src/main/java/com/WhatIsMethIs/config/BaseResponseStatus.java b/src/main/java/com/WhatIsMethIs/config/BaseResponseStatus.java index f23eeaf..4f78418 100644 --- a/src/main/java/com/WhatIsMethIs/config/BaseResponseStatus.java +++ b/src/main/java/com/WhatIsMethIs/config/BaseResponseStatus.java @@ -25,6 +25,8 @@ public enum BaseResponseStatus { POST_USERS_INVALID_PHONENUMBER(false, 2012, "전화번호 형식을 확인해주세요."), EXIST_EMAIL(false,2013,"이미 가입한 이메일입니다."), + FILE_NOT_FOUND_EXCEPTION(false, 2014, "파일이 없습니다."), + /** * 3000 : Response 오류 */ diff --git a/src/main/java/com/WhatIsMethIs/src/controller/MedicineController.java b/src/main/java/com/WhatIsMethIs/src/controller/MedicineController.java index 4736cc6..c96e169 100644 --- a/src/main/java/com/WhatIsMethIs/src/controller/MedicineController.java +++ b/src/main/java/com/WhatIsMethIs/src/controller/MedicineController.java @@ -2,15 +2,21 @@ import com.WhatIsMethIs.config.BaseException; import com.WhatIsMethIs.config.BaseResponse; +import com.WhatIsMethIs.src.dto.medicine.MedicineDto; import com.WhatIsMethIs.src.dto.medicine.MedicineResponseDto; +import com.WhatIsMethIs.src.dto.medicine.PillImageDto; import com.WhatIsMethIs.src.service.MedicineService; +import com.WhatIsMethIs.src.service.PillImageService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.HashMap; +import java.util.List; import static com.WhatIsMethIs.config.BaseResponseStatus.OPEN_API_ERROR; @@ -20,6 +26,7 @@ @Tag(name = "MEDICINE", description = "약물 정보 API") public class MedicineController { private final MedicineService medicineService; + private final PillImageService pillImageService; /** * 2.1.1 약물 정보 전체 조회 @@ -55,4 +62,29 @@ else if(!paramMap.containsKey("itemName") && paramMap.containsKey("itemSeq")){ return new BaseResponse<>(exception.getStatus()); } } + + /** + * TODO 2.1.4 약물 이미지로 식별 + * [POST] /medicines/identify + */ + @PostMapping("/identify") + public BaseResponse postPillImageAndGetInfo( + @Valid @RequestParam("files") List images + ) + { + MedicineResponseDto medicineResponseDto = null; + + try{ + // TODO 모델 서버에 식별 요청 + // 현재는 이미지와 관계 없이 임의의 약물 정보 송신 + medicineResponseDto = medicineService.getMedicinesByItemSeq("202001927"); + + // 이미지 로컬 디렉토리에 저장 + pillImageService.addPillImage(images); + }catch (BaseException exception){ + return new BaseResponse<>(exception.getStatus()); + } + + return new BaseResponse<>(medicineResponseDto); + } } diff --git a/src/main/java/com/WhatIsMethIs/src/dto/medicine/PillImageDto.java b/src/main/java/com/WhatIsMethIs/src/dto/medicine/PillImageDto.java new file mode 100644 index 0000000..75bf0d5 --- /dev/null +++ b/src/main/java/com/WhatIsMethIs/src/dto/medicine/PillImageDto.java @@ -0,0 +1,35 @@ +package com.WhatIsMethIs.src.dto.medicine; + +import com.WhatIsMethIs.src.entity.PillImage; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class PillImageDto { + private int id; + private String originalFileName; + private String storedFilePath; + private long fileSize; + private LocalDateTime createdAt; + + public static PillImageDto toDto(PillImage pillImage){ + PillImageDto pillImageDto = new PillImageDto(); + + pillImageDto.id = pillImage.getId(); + if(pillImage.getOriginalFileName() != null){ + pillImageDto.originalFileName = pillImage.getOriginalFileName(); + } + if(pillImage.getStoredFilePath() != null){ + pillImageDto.storedFilePath = pillImage.getStoredFilePath(); + } + pillImageDto.fileSize = pillImage.getFileSize(); + if(pillImage.getCreatedAt() != null){ + pillImageDto.createdAt = pillImage.getCreatedAt(); + } + + return pillImageDto; + } +} diff --git a/src/main/java/com/WhatIsMethIs/src/entity/PillImage.java b/src/main/java/com/WhatIsMethIs/src/entity/PillImage.java new file mode 100644 index 0000000..3f272c7 --- /dev/null +++ b/src/main/java/com/WhatIsMethIs/src/entity/PillImage.java @@ -0,0 +1,53 @@ +package com.WhatIsMethIs.src.entity; + +import com.WhatIsMethIs.src.dto.medicine.PillImageDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Entity +@Table(name = "pill_image") +@NoArgsConstructor +@Schema(description = "식별 요청 이미지") +public class PillImage { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + @Column(name = "original_file_name") + @NotEmpty + private String originalFileName; + @Column(name = "stored_file_path") + @NotEmpty + private String storedFilePath; + @Column(name = "file_size") + private long fileSize; + @CreationTimestamp + @Column(name = "created_at") + private LocalDateTime createdAt; + + public static PillImage toEntity(PillImageDto pillImageDto){ + PillImage pillImage = new PillImage(); + + pillImage.id = pillImageDto.getId(); + if(pillImageDto.getOriginalFileName() != null){ + pillImage.originalFileName = pillImageDto.getOriginalFileName(); + } + if(pillImageDto.getStoredFilePath() != null){ + pillImage.storedFilePath = pillImageDto.getStoredFilePath(); + } + pillImage.fileSize = pillImageDto.getFileSize(); + if(pillImageDto.getCreatedAt() != null){ + pillImage.createdAt = pillImageDto.getCreatedAt(); + } + + return pillImage; + } +} diff --git a/src/main/java/com/WhatIsMethIs/src/repository/PillImageRepository.java b/src/main/java/com/WhatIsMethIs/src/repository/PillImageRepository.java new file mode 100644 index 0000000..926e782 --- /dev/null +++ b/src/main/java/com/WhatIsMethIs/src/repository/PillImageRepository.java @@ -0,0 +1,7 @@ +package com.WhatIsMethIs.src.repository; + +import com.WhatIsMethIs.src.entity.PillImage; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PillImageRepository extends JpaRepository { +} diff --git a/src/main/java/com/WhatIsMethIs/src/service/PillImageService.java b/src/main/java/com/WhatIsMethIs/src/service/PillImageService.java new file mode 100644 index 0000000..fe075b0 --- /dev/null +++ b/src/main/java/com/WhatIsMethIs/src/service/PillImageService.java @@ -0,0 +1,57 @@ +package com.WhatIsMethIs.src.service; + +import com.WhatIsMethIs.config.BaseException; +import com.WhatIsMethIs.config.BaseResponseStatus; +import com.WhatIsMethIs.src.dto.medicine.PillImageDto; +import com.WhatIsMethIs.src.entity.PillImage; +import com.WhatIsMethIs.src.repository.PillImageRepository; +import com.WhatIsMethIs.utils.FileHandler; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class PillImageService { + private final PillImageRepository pillImageRepository; + + private final FileHandler fileHandler; + + public List addPillImage( + List files + ) throws BaseException { + List pillImageDtos = new ArrayList<>(); + + try { + List list = fileHandler.parseImageInfo(files); + if(list.isEmpty()){ + throw new BaseException(BaseResponseStatus.FILE_NOT_FOUND_EXCEPTION); + } + + /*for(PillImageDto pillImageDto : list){ + PillImage pillImage = new PillImage(); + pillImage.setOriginalFileName(pillImageDto.getOriginalFileName()); + pillImage.setStoredFilePath(pillImageDto.getStoredFilePath()); + pillImage.setFileSize(pillImageDto.getFileSize()); + pillImage.setCreatedAt(pillImageDto.getCreatedAt()); + System.out.println(pillImage.getId()); + + pillImageDtos.add( + PillImageDto.toDto( + pillImageRepository.save( + pillImage + ) + ) + ); + }*/ + } catch (Exception e) { + throw new BaseException(BaseResponseStatus.FILE_NOT_FOUND_EXCEPTION); + } + + return pillImageDtos; + } +} diff --git a/src/main/java/com/WhatIsMethIs/utils/FileHandler.java b/src/main/java/com/WhatIsMethIs/utils/FileHandler.java new file mode 100644 index 0000000..6a7c434 --- /dev/null +++ b/src/main/java/com/WhatIsMethIs/utils/FileHandler.java @@ -0,0 +1,88 @@ +package com.WhatIsMethIs.utils; + +import com.WhatIsMethIs.src.dto.medicine.PillImageDto; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Component +public class FileHandler { + public List parseImageInfo( + List multipartFiles + ) throws IOException { + // 반환을 할 파일 리스트 + List fileList = new ArrayList<>(); + + // 파일이 빈 것이 들어오면 빈 것을 반환 + if(multipartFiles.isEmpty()){ + return fileList; + } + + // 파일 이름을 업로드 한 날짜로 바꾸어서 저장 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); + String current_date = simpleDateFormat.format(new Date()); + + // 프로젝트 폴더에 저장하기 위해 절대경로를 설정 (Window 의 Tomcat 은 Temp 파일을 이용) + String absolutePath = new File("").getAbsolutePath() + "\\"; + + // 경로를 지정하고 이미지 저장 + String path = "images/" + current_date; + File file = new File(path); + // 저장할 위치의 디렉토리가 존지하지 않을 경우 + if(!file.exists()){ + // mkdir() 함수와 다른 점은 상위 디렉토리가 존재하지 않을 때 그것까지 생성 + file.mkdirs(); + } + + // 파일 처리 + for (MultipartFile multipartFile : multipartFiles){ + // 파일이 비어 있지 않을 때 작업을 시작 + if(!multipartFile.isEmpty()){ + // jpeg, png, gif 파일들만 받아서 처리 + String contentType = multipartFile.getContentType(); + String originalFileExtension; + // 확장자 명이 없으면 이 파일은 잘 못 된 것 + if (ObjectUtils.isEmpty(contentType)){ + break; + } + else{ + if(contentType.contains("image/jpeg")){ + originalFileExtension = ".jpg"; + } + else if(contentType.contains("image/png")){ + originalFileExtension = ".png"; + } + else if(contentType.contains("image/gif")){ + originalFileExtension = ".gif"; + } + // 다른 파일 명이면 break + else{ + break; + } + } + // 각 이름은 겹치면 안되므로 나노 초까지 동원하여 지정 + String new_file_name = Long.toString(System.nanoTime()) + originalFileExtension; + // 생성 후 리스트에 추가 + PillImageDto pillImageDto = new PillImageDto(); + pillImageDto.setOriginalFileName(multipartFile.getOriginalFilename()); + pillImageDto.setStoredFilePath(path + "/" + new_file_name); + pillImageDto.setFileSize(multipartFile.getSize()); + fileList.add(pillImageDto); + + // 저장된 파일로 변경하여 이를 보여주기 위함 + System.out.println(absolutePath + path + "/" + new_file_name); + file = new File(absolutePath + path + "/" + new_file_name); + multipartFile.transferTo(file); + } + } + + return fileList; + } +} From e00a4ead48b4f7cddd859b54beb81657bdf547a3 Mon Sep 17 00:00:00 2001 From: Park MinJe Date: Sun, 20 Aug 2023 05:10:08 +0900 Subject: [PATCH 2/2] update release file --- .../WhatIsMethIs-Server-0.0.1-SNAPSHOT.jar | Bin 57696020 -> 57701357 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/WhatIsMethIs-Server-0.0.1-SNAPSHOT.jar b/release/WhatIsMethIs-Server-0.0.1-SNAPSHOT.jar index f3018f00065999a363ca309cde93b1543ff72823..fa2c25fc7e6579d56bab875bd7ed2d96a5ab975c 100644 GIT binary patch delta 18711 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 lR;!i-Y}w%z8m8jsx!uNc7Tld#SUTZ96