-
Notifications
You must be signed in to change notification settings - Fork 2
Trouble Shooting
하물 edited this page Oct 3, 2022
·
25 revisions
update 함수가 작동하지 않는 문제
해당 update문을 지날 때, response값으로는 변경된 값이 적용되나 실제도 DB상에 적용되지 않는 상황. member값이 순간동안 바뀌나 변경감지가 제대로 작동하지 않았음을 확인.
- @Dynamic을 추가하여 변경된 컬럼만 업데이트 쿼리를 날린다. update함수가 실행하지 못하는 이유가 쿼리의 문제라고 여겨 추가하였으나 변함없음 → @DYNAMIC은 단점이 많은 어노테이션으로 되도록 쓰지 않아야 한다.
- @Transactional을 추가하여 영속성을 유지. 다만 그럼에도 update쿼리 작동 안함
- memberRepository.save(member) 을 통해 저장 ⇒ update가 작동하지 않는 근본적인 원인을 해결하지 못함
JPARepository를 상속받은 Repository에서 정보를 불러와야 JPA의 함수가 작동할 수 있다. 즉, request의 헤더에서 파싱한 member정보는 JPA 자체가 시동되지 못한다. 즉, JPA의 변경감지가 작동하지 않아 update함수로 인하여 member값은 일시적으로 변하고 ResponseDto에 적용이 되지만 실질적으로 DB에 적용되지 않는다. 그렇기에 JPA의 변경감지를 상속받은 리포지토리에서 불러온 member값은 update로 변환된 값이 변경감지로 인식되어 DB값도 변경되게 된다.
multipartFile이 아닌 Base64파일을 S3에 업로드하게 된 상황
- 촬영한 사진은 이미지 파일이 아닌 Base64파일로 서버로 넘어오게 된다.
- @RequestParam으로 가져오려 했으나 Base64길이가 너무 길어 에러가 남
- @RequestBody로 변경하여서 받았지만 저장되지 않음. (MultipartFile로 변환이 필요함)
- Base64 를 File로 변환하고 File을 MultipartFile로 변환하여 시도 → contentType이 nullException이 뜨는 현상 발생
public class Base64Util {
public File getImageFromBase64(String base64String, String fileName) {
String[] strings = base64String.split(",");
String extension;
switch (strings[0]) { // check image's extension
case "data:image/jpeg;base64":
extension = "jpeg";
break;
case "data:image/png;base64":
extension = "png";
break;
default:
extension = "jpg";
break;
}
byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
File file = new File(fileName + extension);
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file))) {
outputStream.write(data);
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
public MultipartFile convertFileToMultipartFile(File file) throws IOException {
FileItem fileItem = new DiskFileItem("file"
, Files.probeContentType(file.toPath())
, false, file.getName()
, (int) file.length(),
file.getParentFile());
try {
InputStream is = new FileInputStream(file);
OutputStream os = fileItem.getOutputStream();
IOUtils.copy(is, os);
} catch (IOException e) {
throw new IOException(e);
}
return new CommonsMultipartFile(fileItem);
}- image type에서 “.”을 추가하여 확장자를 만들어줌으로서 contentType 생성 → 버킷으로 저장 완료. 하지만 file이 서버에 저장되는 현상 발생
switch (strings[0]) { // check image's extension
case "data:image/jpeg;base64":
extension = ".jpeg";
break;
case "data:image/png;base64":
extension = ".png";
break;
default: // should write cases for more images types
extension = ".jpg";
break;
}- 서버에 저장되는 사진을 삭제하는 로직을 추가→ 사진이 삭제 되지 않음
private void removeNewFile(File targetFile) {
if(targetFile.delete()) {
log.info("파일이 삭제되었습니다.");
}else {
log.info("파일이 삭제되지 못했습니다.");
}
}- 서버에 사진을 저장하지 않기 위해 S3Uploader에서 바로 Base64파일을 업로드하는 로직 구현 → 버킷에 확장자 명이 안나타나는 문제 발생
public String getImgUrlBase64(String base64){
String[] strings = base64.split(",");
String extension = switch (strings[0]) {
case "data:image/jpeg;base64" -> ".jpeg";
case "data:image/png;base64" -> ".png";
default -> // should write cases for more images types
".jpg";
};
byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
long now = new Date().getTime();
String fileName = UUID.randomUUID().toString() + now;
InputStream img = new ByteArrayInputStream(data);
ObjectMetadata metadata = new ObjectMetadata();
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, img, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString();
}- fileName에 extention을 추가함 → 저장된 사진이 바로 다운로드가 되는 현상 발견 (버킷에 업로드 할 때 콘텐트 타입이 저장되지 않으면 형식을 알 수없어 바로 다운로드가 된다는 사실을 발견)
byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
long now = new Date().getTime();
String fileName = UUID.randomUUID().toString() + now + extension;
metadata.setContentType("image/"+extension.substring(1));
metadata.setCacheControl("public, max-age=31536000");
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, img, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString();
}- ObjectMetadata에 콘텐트 타입과 길이 증을 설정. → 버킷에 정상 저장.
byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
long now = new Date().getTime();
String fileName = UUID.randomUUID().toString() + now + extension;
InputStream img = new ByteArrayInputStream(data);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(data.length);
metadata.setContentType("image/"+extension.substring(1));
metadata.setCacheControl("public, max-age=31536000");
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, img, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString();
}- S3에 Base64를 바로 업로드 하여 서버에 파일 저장 방지
- S3 업로드 시 contentType을 반드시 설정하여 다운로드가 되지 않도록 수정
내역을 변경이 가능한 테이블로 사용하지 않고 내역을 따로 저장하는 테이블의 필요성을 느낌
- 데이터 베이스 관리
- 관리자 페이지 운영 시, 관리자의 원활한 문의 처리를 위함 ****
- JPA @PrePersist 와 @PreUpdate를 통하여 테이블 자동 생성(내역 테이블을 직접 설정할 수 있다 다만 많은 코드와 설정이 필요)
- envers를 사용하여 @Audited로 Rev파일 자동 생성. (테이블의 변경에 따라 자동 생성)
- envers를 사용한 방법이 코드의 양이 적어지고 또 간편하게 내역을 생성 할 수 있어 선택.
@RequestBody에 있는 값이 제대로 들어가지 않음
- postman으로 body에 String값을 그냥 써넣으면 제대로 들어가지만 json으로 받으면 받아지지 않는다.
- Body내에 있는 문자열을 모두 받아오는 현상 발생.
- 문자열만 전송하자 위와같이 이상한 문자열로 변환됨
- Map{String,String} 을 사용하여 값을 받음
- 할 수 있는 방법: requestDto를 사용하여 매핑을 해주는 방식
**이미지 리사이징 로직이 작동하지 않음 ###2. 시도한 방법
- 콘솔로 찍어보니 imageIcon에서 getWidth,한 값이 -1로 찍히는 것을 확인
- 길이와 넓이가 잘 나오지만 비율이 맞춰지지 않는 것을 확인
- 추가한 코드
publicImageSizeDtodefineSize(intheight, intwidth) {
if (height>width) {
double ratio = (double)width/ 320;
int resizedHeight = (int) (height/ ratio);
log.info(height+" "+width);
return (new ImageSizeDto(resizedHeight, 320));
}
int ratio =height/ 320;
int resizedWidth =width/ ratio;
log.info(height+" "+width);
return (new ImageSizeDto(320, resizedWidth));
}- BufferedImage로 변환시 null이 뜨는 오류
- 시도한 코드
Image resizedImage = image.getScaledInstance(sizeDto.getWidth(), sizeDto.getHeight(), Image.SCALE_SMOOTH);
ImageInputStream resizedImageInputStream = ImageIO.createImageInputStream(resizedImage);- SdkClientException:Data read has a different length than the expected
- 시도한 코드
IOUtils.toByteArray(resizedImg).length- 시도한 코드
resizedImg.readAllBytes().length- 리사이징 된 이미지 data 0 bite
- 시도한 코드
log.info("이미지 : "+ width + " " + height);
BufferedImage outputImage = new BufferedImage(sizeDto.getWidth(), sizeDto.getHeight(), inputImage.getType());
log.info("이미지 : " + sizeDto.getHeight() + " " + sizeDto.getWidth());
Graphics graphics2D = outputImage.getGraphics();
graphics2D.drawImage(resizedImage, 0, 0, null); // 그리기
graphics2D.dispose(); // 자원해제
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(outputImage, "png", os);
log.info("이미지 DONE");
return new ByteArrayInputStream(os.toByteArray());- 해결한 코드
publicStringgetImgUrlBase64(Stringbase64) throwsIOException{
String[] strings =base64.split(",");
Stringextension = switch (strings[0]) {// check image's extension
case "data:image/jpeg;base64" -> ".jpeg";
case "data:image/png;base64" -> ".png";
case "data:image/webp;base64" -> ".webp";
default -> ".jpg";
};
byte[] data =DatatypeConverter.parseBase64Binary(strings[1]);
InputStream imgStream = new ByteArrayInputStream(data);
InputStream resizedImg = checkImage(imgStream);
ObjectMetadatametadata = new ObjectMetadata();
metadata.setContentLength(resizedImg.available());
metadata.setContentType("image/" + extension.substring(1));
metadata.setCacheControl("public, max-age=31536000");
long now = new Date().getTime();
StringfileName = now + "_" +UUID.randomUUID() + extension;
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, resizedImg, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString();
}
public InputStream checkImage(InputStreamimgStream) throwsIOException{
BufferedImageinputImage =ImageIO.read(imgStream);
int imageHeight = inputImage.getHeight(null);
int imageWidth = inputImage.getWidth(null);
if (imageHeight > 320 && imageWidth > 320) return resize(inputImage, imageWidth, imageHeight);
else {
ByteArrayOutputStreamoutStream = new ByteArrayOutputStream();
ImageIO.write(inputImage,"png",outStream);
return new ByteArrayInputStream(outStream.toByteArray());
}
}
/*리사이즈 실행 메소드 */
public InputStream resize(BufferedImageinputImage, intwidth, intheight) throwsIOException{
ImageSizeDtosizeDto = defineSize(height,width);
Image resizedImage =inputImage.getScaledInstance(sizeDto.getWidth(),sizeDto.getHeight(),Image.SCALE_SMOOTH);
BufferedImageoutputImage = new BufferedImage(sizeDto.getWidth(), sizeDto.getHeight(),inputImage.getType());
Graphics graphics2D = outputImage.getGraphics();
graphics2D.drawImage(resizedImage, 0, 0, null);//그리기
graphics2D.dispose();//자원해제
ByteArrayOutputStreamos = new ByteArrayOutputStream();
ImageIO.write(outputImage, "png", os);
return new ByteArrayInputStream(os.toByteArray());
}
publicImageSizeDtodefineSize(intheight, intwidth) {
if (height>width) {
double ratio = (double)width/ 320;
int resizedHeight = (int) (height/ ratio);
return (new ImageSizeDto(resizedHeight, 320));
}
int ratio =height/ 320;
int resizedWidth =width/ ratio;
return (new ImageSizeDto(320, resizedWidth));
}