본문 바로가기
Spring

[Spring] 데이터와 연관된 파일 데이터(multipart)를 목록으로 받기

by 흑시바 2023. 4. 2.

프로젝트 진행 중에 '하나의 데이터 정보'와 연관된 '여러 파일 데이터 정보'를 조합한 '묶음 데이터'를 리스트로 받아야 하는 경우가 있었다. 파일 데이터 전송을 위해 FormData 전송 형식을 선택하게 되었고, Spring 서버에서 어떻게 해당 데이터 형식을 받을 수 있을지 고민하고 여러 방식을 시도했다. 😾

 

그래서 해당 포스팅에는 데이터와 연관된 파일 데이터를 목록으로 받는 방법과 Postman으로 수동 테스트 하는 방법에 대해 공유한다. 👊

 

위의 이미지처럼 하나의 데이터 당 여러 개의 첨부 파일을 가질 수 있는 형태의 목록을 서버에서 받아야 하는 상황이다.

 

데이터와 파일들은 서로 연관이 있는 데이터들이므로 특정 파일들이 특정 데이터와 연관되어 있다는 걸 서버에서 확인할 수 있어야 하고, 이를 목록 형태로 받아서 한 번의 Request로 처리해야 한다.

🤜 [Controller & Object]

@PostMapping("/api/shiba")
@ResponseStatus(HttpStatus.OK)
public void insertShiba(@ModelAttribute Shiba shibaList) {

	System.out.println(shibaList);
}


@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Shiba {

	private List<Item> shibaList;

}

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Item {
        
	private ShibaData data;
	private List<MultipartFile> files;
}


@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ShibaData {

	private Long id;
	private String name;
}

 

위 코드는 컨트롤러와 객체를 구현한 내용이다. Content-type이 multipart/form-data 형식이므로 @ModelAttribute를 사용하였고 @ModelAttribute는 Setter에 넘어온 값을 주입하기 때문에 편의상 Dto에 @Data lombok 어노테이션을 사용했다.

🤜 [TEST]

 

그다음 Postman에서 테스트를 진행한다.

 

Body 부분에 form-data 형식을 선택하고, 위 이미지처럼 Array.data.id 형식으로 필드에 맞게 값을 추가하면 된다.

파일 형식은 각 KEY 행에 마우스 오버하면 File과 Text 중에서 선택이 가능하다.

 

 

Request 요청을 보내고 서버에서 디버깅하여 확인하면 데이터와 파일이 요청에 맞게 정확히 주입된 것을 확인할 수 있다.

 

그런데 실제로 프로젝트에서 사용하는 Dto에는 필드가 훨씬 많은데, 이렇게 일일이 필드를 추가해서 수동 테스트를 진행하는 것은 굉장히 번거롭다.

 

그럴 때는 위 이미지처럼 하나의 key에 JSON 형태로 값을 넣어서 전달하는 방식으로 해결할 수 있다.

 

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Item {

	private static final ObjectMapper mapper = new ObjectMapper();

	private ShibaData data;
	private List<MultipartFile> files;

	public void setData(String data) {
		try {
			this.data = mapper.readValue(data, ShibaData.class);
		} catch (JsonProcessingException e) {
			throw new RuntimeException(e);
		}
	}
}

 

또한, @ModelAttribute는 Setter를 활용한다는 점을 이용해서 자바빈즈 규칙에 맞게 별도의 setter 메서드를 생성하여 데이터를 파싱 해주면 된다.

 

댓글