13. 스프링부트 파일 등록하기

2025. 4. 9. 09:09현 프로젝트 시작단계

728x90

기본 설정에

 

일단 파일등록하기 위해서 file 경로를 제대로 설정 해줘야 합니다.

file:
  directory: D:\KWJ\feed

 

 

 

 

 

이제 feedpicmapper.xml 파일을 하나만들어줍니다

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.modir.feed.FeedPicMapper">


    <insert id="insFeedPic">
        INSERT INTO feed_pic
        ( feed_id, pic )
        VALUES
        <foreach collection="pics" item="pic" open="(" close=")" separator="),(">
            #{feedId} , #{pic}
        </foreach>
    </insert>

</mapper>

 

 

<mapper namespace="com.example.modir.feed.FeedPicMapper">
  • 네임스페이스를 정의하여 이 매퍼 파일이 속한 Java 인터페이스를 지정
  • com.example.modir.feed.FeedPicMapper는 해당 매퍼와 연결된 Java 인터페이스의 풀 패키지 경로

 

<insert id="insFeedPic">
  • 데이터베이스에 데이터를 삽입하는 SQL 쿼리를 정의
  • id="insFeedPic"은 Java 코드에서 이 쿼리를 호출할 때 사용할 식별자

 

 

<foreach collection="pics" item="pic" open="(" close=")" separator="),("> #{feedId} , #{pic} </foreach>
이 매퍼는 feed_pic 테이블에 여러 개의 피드 사진 데이터를 한 번에 삽입하는 기능을 한다.
<foreach>를 사용해 동적으로 여러 행을 삽입하므로, 사진 개수에 상관없이 유연하게 처리 가능

 

 

위에 xml파일과 연결을 하기위해 매퍼를 만들어줍니다. 

package com.example.modir.feed;


import com.example.modir.feed.model.FeedPicDto;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface FeedPicMapper {
    int insFeedPic(FeedPicDto p);
}

 


다음은 dto 와 res 와 req를 만들어야되는데

밑에처럼 만들어줍니다.

public class InsFeedReq {
    @JsonIgnore //  숨기는거 스웨거 상에서 피드아이디를 안보이게 숨김
    private long feedId;
    private String title;
    private String content;
    private String uuid;
}

어노테이션: @JsonIgnore

  • 역할:
    • Jackson 라이브러리(자바에서 JSON 직렬화/역직렬화를 담당)에서 사용하는 어노테이션.
    • 이 필드가 JSON으로 변환되거나 JSON에서 객체로 변환될 때 무시되도록 설정.
  • 효과:
    • 클라이언트가 이 객체를 JSON 형태로 보낼 때 feedId는 포함되지 않음.
    • 서버가 이 객체를 JSON으로 반환할 때도 feedId는 노출되지 않음.

feedId를 숨겼을까?

  • feedId는 서버에서 자동 생성되는 값(예: DB의 Auto Increment)이라 클라이언트가 입력할 필요가 없음.
package com.example.modir.feed.model;


import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter

public class FeedPicDto {
    private long feedId;
    private List<String> pics;
}
package com.example.modir.feed.model;


import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Setter
@Getter
public class FeedPostRes {
    private long FeedId;
    private List<String> pics;
}

FeedPicDto를 만든이유는? 모르겠음.. 센세 에게 물어보기

 


피드 서비스 코드

    private final FeedMapper feedMapper;
    private final MyFileUtils myFileUtils;
    private final FeedPicMapper feedPicMapper;
  • FeedMapper feedMapper: 피드 데이터를 DB에 삽입.
  • MyFileUtils myFileUtils: 파일 처리 유틸리티 (폴더 생성, 파일 저장 등).
  • FeedPicMapper feedPicMapper: 피드와 관련된 사진 데이터를 DB에 삽입.
public FeedPostRes postFeed(InsFeedReq req, List<MultipartFile> pics) {
        int result = feedMapper.insFeed(req); // 생성하는거 피드 id

        long feedId = req.getFeedId(); //가져오는거


        String middlePath = String.format("feed/%d", feedId);
        myFileUtils.makeFolders(middlePath);

        List<String> picNameList = new ArrayList<>();
        for (MultipartFile pic: pics){
            String savePicName = myFileUtils.makeRandomFileName(pic);
            picNameList.add(savePicName);
            String filePath = String.format("%s/%s", middlePath, savePicName);

            try {
                myFileUtils.transferTo(pic , filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        FeedPicDto feedPicDto = new FeedPicDto();
        feedPicDto.setFeedId(feedId);
        feedPicDto.setPics(picNameList);
        int resultPic =feedPicMapper.insFeedPic(feedPicDto);

        FeedPostRes res =new FeedPostRes();
        res.setFeedId(feedId);
        res.setPics(picNameList);

        return res;
    }

 

 

1. 피드 삽입 부분

int result = feedMapper.insFeed(req)

 

존 코드와 동일하게 피드 데이터를 DB에 삽입.

삽입 후 feedId req 객체에 설정된다고 가정

(MyBatis에서 <insert> 태그의 useGeneratedKeys="true"로 자동 생성된 ID를 req에 반영).

<insert id="insFeed" useGeneratedKeys="true" keyProperty="feedId">

 

2. 피드 아이디 가져오기

long feedId = req.getFeedId(): 삽입된 피드의 ID를 가져옴.

 

 
3. 사진 저장 경로 준비
String middlePath = String.format("feed/%d", feedId):​
 
피드 ID를 기반으로 저장 경로 생성 (예: feed/123).
 
myFileUtils.makeFolders(middlePath): 해당 경로에 폴더를 생성.
 

 

4. 사진 파일 처리

for (MultipartFile pic : pics): 업로드된 사진을 하나씩 처리.
String savePicName = myFileUtils.makeRandomFileName(pic): 고유한 파일명 생성
String filePath = String.format("%s/%s", middlePath, savePicName): 전체 파일 경로 생성 (예: feed/123/abc123.jpg).
 
 
 
5. 사진 정보 DB 저장:
  • FeedPicDto feedPicDto = new FeedPicDto(): 사진 데이터를 담을 DTO 생성.
  • feedPicDto.setFeedId(feedId): 피드 ID 설정.
  • feedPicDto.setPics(picNameList): 저장된 사진 파일명 리스트 설정.
int resultPic = feedPicMapper.insFeedPic(feedPicDto):
  •  MyBatis 매퍼를 통해 사진 데이터를 DB에 삽입 (앞서 본 <foreach> 쿼리 사용).

 

 

 


피드 컨트롤러

 

 

Spring이 JSON을 파라미터로 매핑하지 못해서 오류가 나는 거야. JSON으로 데이터 받을 땐 반드시

@RequestBody 붙여야 합니다 근데 @RequestPart 을 붙이는 이유는 지금 두개를 받고 있으니까

두개를 받을때는 파트로 해줘야함 

 

@PostMapping
@Operation(summary = "게시글 등록")
public ResultResponse<FeedPostRes> postFeed(@RequestPart(required = false)List<MultipartFile> pics
                                        ,@RequestPart InsFeedReq req){
    FeedPostRes result = feedService.postFeed(req, pics);

    return ResultResponse.<FeedPostRes>builder()
            .resultMessage("피드 등록 완료")
            .resultData(result)
            .build();
}

 

 

여기까지 하게 되면 

포스트맨에도 적어줘야함 

https://www.postman.com/downloads/

 

Download Postman | Get Started for Free

Try Postman for free! Join 35 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

이 친구 다운로드 후 

상단에 body 클릭

 

1. req 적기  

->

 

2. json 데이터 적기

 

{
"title": "string",
"content": "string",
"uuid": "123"
}
 
->
3. application/json  텍스트 적기
 

 

두번째 행에 

1. pics 적어주고

2. 파일 하나 넣어줍니다.

 

그리고 자신이 만든  api 경로에 따라 

 

주소를 넣어줍니다 post로 

 

send를 누르고

 

사진 데이터가 잘 전달 되었는지 확인 

잘 전달

 

 

 

 

포스트맨에서 사진이 포함된 게시물을 하나 넘겨준다. 

한마디로 백엔드에서 사진을 보내서 테스트를 도와주는 도구 인거같다.

728x90