๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“• Spring Framework/Spring Project

ใ€ŒํŒŒ์ผ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ ๋ฐ ํ…Œ์ŠคํŠธใ€

by GroovyArea 2022. 7. 1.
์ด๋ฒˆ ์ฃผ์— Sonarqube๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์ ์šฉํ•˜๊ธฐ ์ „ ์ „์ฒด์ ์ธ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๊ฒ€ํ†  ์ค‘์ด์—ˆ๋‹ค. 
๋นผ๋†“์€ ํ•„์ˆ˜์ ์ธ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์ƒํ’ˆ ํ…Œ์ด๋ธ”์—๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ด๋ฆ„ ์นผ๋Ÿผ์ด ์กด์žฌํ•˜๋Š”๋ฐ ์ด๋ฅผ ๊นœ๋ฐ•ํ–ˆ๋˜ ๊ฒƒ์ด๋‹ค. 
ํŒŒ์ผ ์—…๋กœ๋“œ, ๋‹ค์šด๋กœ๋“œ ๊ธฐ๋Šฅ์„ ๊ธ‰ํ•˜๊ฒŒ ์ ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , ์ด ๊ณผ์ •์„ ๊ธฐ๋ก์œผ๋กœ ์ž‘์„ฑํ•˜๊ฒ ๋‹ค.

ํŒŒ์ผ ์—…๋กœ๋“œ

ํŒŒ์ผ์„ ๋“ฑ๋กํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ํƒ€์ž…์œผ๋กœ ์Šคํ”„๋ง์—์„œ๋Š” MultipartFile ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. 

์ด๋ฅผ ํ†ตํ•ด ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฐ ๋‹ค์šด๋กœ๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

ํŒŒ์ผ ์—…๋กœ๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๋‚ด API๋Š” ์ƒํ’ˆ ์ถ”๊ฐ€์™€ ์ˆ˜์ •์ด๋‹ค.

 

๋จผ์ € ํŒŒ์ผ ์—…๋กœ๋“œํ•  ์œ„์น˜๋ฅผ ๋‚ด๋ถ€ ๊ฒฝ๋กœ์™€ ์™ธ๋ถ€ ๊ฒฝ๋กœ์ค‘ ๊ณ ๋ฏผ์„ ํ–ˆ๋‹ค. ์ €๋ฒˆ ํ”„๋กœ์ ํŠธ ๋•Œ๋Š” ํ”„๋กœ์ ํŠธ ๋‚ด๋ถ€๋กœ ์ง€์ •ํ–ˆ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐฐํฌ ์‹œ ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ๋ฅผ ๋ชป ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ํ”„๋กœ์ ํŠธ ์™ธ๋ถ€ ๊ฒฝ๋กœ๋กœ ์ง€์ •ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

 

application.yml์— ์ •์˜ํ•œ ๊ฒฝ๋กœ
Service์—์„œ @Value ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ yml ๊ฐ’์„ ๋ฐ›์•„์˜จ๋‹ค.

์šฐ์„ ,

ํŒŒ์ผ ์—…๋กœ๋“œ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด @RequestParam ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ Multipartfile ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค. 

public ResponseEntity<?> addAction(@ModelAttribute ProductDTO productDTO,
                                   @RequestParam("image") MultipartFile file) throws IOException {

 

ํŒŒ์ผ ์—…๋กœ๋“œ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๊ธฐ ๋•Œ๋ฌธ์— Service ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ์„ ์–ธํ•˜์—ฌ ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ–ˆ๋‹ค. 

public String uploadFile(MultipartFile productImageFile) throws IOException {
    String originalFileName = productImageFile.getOriginalFilename();

    UUID uuid = UUID.randomUUID();

    String uploadFileName = uuid + "_" + originalFileName;

    File file = new File(uploadDirectory, uploadFileName);

    productImageFile.transferTo(file);

    return uploadFileName;
}

=> ์ค‘๋ณต ํŒŒ์ผ๋ช…์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด UUID ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด ์—…๋กœ๋“œ ํ•  ํŒŒ์ผ๋ช…์„ ์ •์˜ํ•ด ์ €์žฅํ–ˆ๋‹ค.

 

ํŒŒ์ผ ์‚ญ์ œ์˜ ๊ฒฝ์šฐ๋Š” ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.

public void deleteFile(String productImageName) {
    File existingFile = new File(uploadDirectory, productImageName);
    if (existingFile.exists()) {
        existingFile.delete();
    }
}

 

ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ

ํŒŒ์ผ ์—…๋กœ๋“œ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์— ํŒŒ์ผ์„ ์ €์žฅ์‹œ์ผฐ๋‹ค. 

API๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€๋ฅผ ์–ป์œผ๋ ค๋ฉด ์ „์ฒด ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ํŒŒ์ผ์„ ์‘๋‹ตํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๋น„ํšจ์œจ์ ์ด๋ผ ํŒ๋‹จ์„ ํ–ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ๊ธฐ๋ณธ์ ์ธ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด Get ์š”์ฒญ ์‹œ์—๋Š” ๋‹ค์šด๋กœ๋“œ URI๋ฅผ ๋„˜๊ฒจ์ฃผ๊ณ ,

์ด URI๋ฅผ ์ด์šฉํ•ด ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค๊ณ„ํ–ˆ๋‹ค.

 

=> ์ƒํ’ˆ ์กฐํšŒ๋ฅผ ํ•˜๋ฉด ๋‹ค์šด๋กœ๋“œ URI๋ฅผ ๋„˜๊ธด๋‹ค.

 

์ด๋ฅผ ํ†ตํ•ด Get ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด์ž

=> ๋นจ๊ฐ„์ƒ‰ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ–ˆ์œผ๋ฏ€๋กœ ์ด ๊ทธ๋ฆผ์„ ์‘๋‹ต๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

public Resource loadFile(String fileName) throws FileNotFoundException {
    try {
        Path directoryLocation = Paths.get(uploadDirectory)
                .toAbsolutePath().normalize();

        Path file = directoryLocation.resolve(fileName).normalize();
        Resource resource = new UrlResource(file.toUri());

        if (resource.exists() || resource.isReadable()) {
            return resource;
        } else {
            throw new FileNotFoundException(FILE_NOT_FOUNT);
        }
    } catch (MalformedURLException e) {
        throw new FileNotFoundException(FAILED_DOWNLOAD);
    }
}

=> ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ๋ฅผ ์œ„ํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ

 

@GetMapping("/download/{fileName}")
public ResponseEntity<Resource> getDownloadFile(@PathVariable String fileName, HttpServletRequest request) throws IOException {
    Resource resource = fileService.loadFile(fileName);

    String contentType;

    try {
        contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
    } catch (IOException e) {
        log.error(FAILED_FILE_CONTENT);
        throw new IOException(FAILED_FILE_CONTENT);
    }

    if (contentType == null) {
        contentType = DEFAULT_CONTENT_TYPE;
    }

    return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType(contentType))
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename())
            .body(resource);
}

=> ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ

 

ํŒŒ์ผ ์—…๋กœ๋“œ์™€ ๋‹ค์šด๋กœ๋“œ๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ–ˆ๋‹ค.

๋‹จ์ผ ์ƒํ’ˆ ์กฐํšŒ

 

์ƒํ’ˆ ๋ชฉ๋ก ์กฐํšŒ

๋ฐ˜์‘ํ˜•