작성
·
252
0
@PutMapping("/{pno}")
public Map<String, String> modify(@PathVariable Long pno, ProductDTO productDTO) {
// productDTO안에 pno값만 고정
productDTO.setPno(pno);
// 원래 상품을 가지고 온다. old product 가져온다. DB에 저장되어 있는 저장된 정보
ProductDTO oldProductDTO = productService.get(pno);
// 새로 업로드할 파일 가져온다.
List<MultipartFile> files = productDTO.getFiles();
// 새로 업로드할 파일 저장
List<String> currentUploadFileNames = fileUtil.saveFiles(files);
// 지워지지 않는 파일들 keep files 예전 파일 그대로 있는 것
List<String> uploadedFileNames = productDTO.getUploadFileNames();
if(currentUploadFileNames != null && !currentUploadFileNames.isEmpty()) {
uploadedFileNames.addAll(currentUploadFileNames);
}
// 수정하기
productService.modify(productDTO);
// 오래된 파일이 문제. 지워져야 하는 파일들 처리
// 기존 파일들을 가져온다.
List<String> oldFileNames = oldProductDTO.getUploadFileNames();
if(oldFileNames != null && !oldFileNames.isEmpty()) {
// 기존 파일 남아 있는지 확인
// uploadedFileNames에서 없다는건 이 파일은 이제 존재할 의미가 없다는것 그런것만 골라서 모은다.
List<String> removeFiles =
oldFileNames.stream().filter(fileName -> uploadedFileNames.indexOf(fileName) == -1 )
.collect(Collectors.toList());
// 삭제한다.
fileUtil.deleteFiles(removeFiles);
}
return Map.of("RESULT", "SUCCESS");
}
ProductController 에 이 메서드를 입력하고
ProductService에는
// 수정
void modify(ProductDTO productDTO);
이걸 입력하고
ProductServiceImpl에는
@Override
public void modify(ProductDTO productDTO) {
// 조회
Optional<Product> result = productRepository.findById(productDTO.getPno());
Product product = result.orElseThrow();
// 변경내용 반영
product.changePrice(productDTO.getPrice());
product.changeName(productDTO.getPname());
product.changeDesc(productDTO.getPdesc());
product.changeDel(productDTO.isDelFlag());
// 이미지 처리를 위해 목록을 비운다.
List<String> uploadFileNames = productDTO.getUploadFileNames();
product.clearList();
if(uploadFileNames != null && uploadFileNames.isEmpty()) {
uploadFileNames.forEach(uploadName ->{
product.addImageString(uploadName);
});
}
// 저장될 때 파일이 문제 파일이 변경됐는지 알 수 가 없다.
productRepository.save(product);
}
private ProductDTO entityToDTO(Product product) {
ProductDTO productDTO = ProductDTO.builder()
.pno(product.getPno())
.pname(product.getPname())
.pdesc(product.getPdesc())
.price(product.getPrice())
.delFlag(product.isDelFlag())
.build();
List<ProductImage> imageList = product.getImageList();
if(imageList == null || imageList.isEmpty()) {
return productDTO;
}
// 상품 이미지 목록 문자열로 바꾸기
List<String> fileNameList = imageList.stream().map(productImage ->
productImage.getFileName()).toList();
productDTO.setUploadFileNames(fileNameList);
return productDTO;
}
이걸 입력하고 postman에서 PUT방식으로 해서 기존 이미지파일 내용을 그대로 복사해서 테스트를 하는데
"msg": "Validation failed for argument [1] in public java.util.Map<java.lang.String, java.lang.String> org.zerock.apiserver.controller.ProductController.modify(java.lang.Long,org.zerock.apiserver.dto.ProductDTO): [Field error in object 'productDTO' on field 'uploadFileNames': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@192a0968]; codes [typeMismatch.productDTO.uploadFileNames,typeMismatch.uploadFileNames,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [productDTO.uploadFileNames,uploadFileNames]; arguments []; default message [uploadFileNames]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.util.List' for property 'uploadFileNames'; Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'uploadFileNames[0]': no matching editors or conversion strategy found]] "
이런 에러가 계속 발생하는데요 왜 그럴까요 ㅠ
postman에서 출력하는 메세지입니다.
GTP에 입력해서 물어봤는데
ProductController
의 modify
메서드에서 ProductDTO
객체의 uploadFileNames
필드가 잘못된 타입으로 전달되었기 때문에 발생합니다.
이런 메세지를 주는데 강의 내용과 똑같이 입력했는데 왜 이런 메세지를 뱉어내는지 잘 모르겠습니다 ㅠ
답변 1
0
해당 강의의 22:17초 근처를 보시면 files라는 이름이 MultipartFile들인데요.. 에러 메시지를 보면
Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'uploadFileNames[0]':
라고 나오고 있습니다.
uploadFileNames는 문자열로 기존에 업로드된 파일들 중에서 남겨두는 파일들이었으니 .. 문자열이 맞습니다.
Postman에서 files는 파일로, uploadFileNames는 문자열로 되었는지 확인해 보셔야 할 듯 하네요
감사합니다 원인을 찾아서 해결했습니다~!