-
6월 29일 목요일 TIL 회고록카테고리 없음 2023. 6. 29. 22:52
어제 TIL을 쓰려했는데 티스토리 블로그 및 사이트를 들어가면 Http 400 에러가 나와서 티스토리 서버가 잠시 터진 줄 알았는데..
오늘도 쓰려하니 똑같이 400에러가 나와서 혹시나 하고 구글링을 해보니 티스토리 쿠키를 지우면 해결된다고 해서 쿠키를 지워봤더니
잘 들어가진다 ㅋㅋㅋ..
어제는 사이트를 꾸며봤다. 검색창이 맨 밑에 있어서 크롬 확대/축소를 75%까지 내려야 검색창이 보였는데 정말 불편해서 수정했다.
검색창을 위로 올리고 가운데에 정렬했다. 지도 및 스카이뷰도 오른쪽으로 옮겼다.
위로 올릴때는 비교적 쉬웠는데 가운데로 옮기려고 참 애먹었다.. 프론트는 오랜만에 만져봐서..
display: flex, justify-content: center 를 사용해서 가운데로 옮겼다.
<div id="search" style="display: flex;justify-content:center;">
카카오 지도도 정렬해주었다.
100vh를 사용했다.
<div id="map" style="width:100%;height:100vh;position:relative;overflow:hidden;"></div>
이제 해야할 것은.. 아이콘 변경 등등 할게 많이 남았다..
프로필을 조회하고 수정하는 코드를 만들었다. 아직 조회 및 수정은 이름밖에 안된다.
프로필 조회 Controller
// 프로필 조회 @GetMapping("/user/me/profile") public ProfileResponse getUserProfile(@AuthenticationPrincipal UserDetailsImpl userDetails) { return userService.getUserProfile(userDetails.getUserId()); }
프로필 조회 Service
// 프로필 조회 @Override @Transactional(readOnly = true) public ProfileResponse getUserProfile(Long userId) { User user = userRepository.findById(userId).orElseThrow( () -> new CustomException(ExceptionStatus.NOT_FOUND_USER) ); return ProfileResponse.builder() .nickname(user.getUsername()) .build(); }
어려운 부분은 딱히 없고 UserDetailsImpl userDetails를 매개변수로 받아 userDetails.getUserId()로 유저 닉네임을 조회한다.
실행 결과
프로필 수정 Controller
// 프로필 (이름 수정) @PutMapping("/user/me/profile") public ResponseEntity<String> updateUserProfile( @AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody ProfileRequest request) { userService.updateUserProfile(userDetails.getUserId(), request); return new ResponseEntity<>("프로필 수정 완료!", HttpStatus.OK); }
프로필 수정 Service
// 프로필 수정 @Override @Transactional public void updateUserProfile(Long userId, ProfileRequest request) { User user = userRepository.findById(userId).orElseThrow( () -> new CustomException(ExceptionStatus.NOT_FOUND_USER) ); user.updateProfile(request.getUsername()); userRepository.save(user); }
실행 결과
그 다음 게시글을 작성할 때 이미지를 넣을 수 있게 multipartFiles를 사용해봤다.
먼저 보드 엔티티에 BoardImage 클래스를 만들었다.
BoardImage.class
@Getter @Entity @NoArgsConstructor(force = true, access = AccessLevel.PROTECTED) public class BoardImage { @Column(nullable = false) private final String imagePath; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "IMAGE_ID") private Long Id; @Column(nullable = false) private String originalName; private Long fileSize; @ManyToOne @JoinColumn(name = "BOARD_ID") private Board board; @Builder public BoardImage(Long id, String originalName, Long fileSize, String imagePath) { this.originalName = originalName; this.fileSize = fileSize; this.imagePath = imagePath; } // Board 정보 저장 public void setBoard(Board board) { this.board = board; // 게시글에 현재 파일이 존재하지 않으면 if (!board.getBoardImageList().contains(this)) { // 파일 추가 board.getBoardImageList().add(this); } } }
하나의 게시글에 여러개의 사진을 추가할 수 있으므로 ManyToOne 어노테이션을 사용해서 BoardImage와 Board 연관관계를 매핑해줬다.
보드 엔티티에도 OneToMany 어노테이션을 사용해서 Board와 BoardImage 연관관계를 매핑해줬다.
Board.class
@OneToMany( mappedBy = "board", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true ) private List<BoardImage> boardImageList = new ArrayList<>(); // Board에서 파일 처리 위함 public void addBoardImage(BoardImage boardImage) { this.boardImageList.add(boardImage); // 게시글에 파일이 저장되어있지 않은 경우 if (boardImage.getBoard() != this) { // 파일 저장 boardImage.setBoard(this); }
그 후 BoardImageRepository 인터페이스를 만들어 준 후 JpaRepository를 상속받았다.
게시글 작성 컨트롤러에 List<MutilpartFile> mutilpartFiles를 매개변수로 받도록 추가해주었다.
기존에는 RequestBody를 사용했는데 RequestPart를 사용하게 만들었다.
BoardController.class
// 게시글 작성 @PostMapping("/basic-boards") public ResponseEntity<String> createBasicBoard( @AuthenticationPrincipal UserDetailsImpl userDetails, @RequestPart("request") @Valid BasicBoardRequest request, @RequestPart(required = false, name = "images") List<MultipartFile> multipartFiles) throws java.io.IOException { basicBoardService.createBasicBoard(userDetails.getUser(), request, multipartFiles); return new ResponseEntity<>("게시글 작성 완료!", HttpStatus.CREATED); }
BasicBoardServiceImpl 클래스에 파일 업로드를 위한 upload 메서드를 만들었다.
// 이미지 업로드 public List<BoardImage> upload(List<MultipartFile> multipartFiles, BasicBoard basicBoard) throws java.io.IOException { // 반환을 할 파일 리스트 List<BoardImage> uploadImagePaths = new ArrayList<>(); // 파일이 빈 것이 들어오면 빈 것을 반환 if (multipartFiles.isEmpty()) { return uploadImagePaths; } // 파일 이름을 업로드 한 날짜로 바꾸어서 저장할 것이다. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); String current_date = simpleDateFormat.format(new Date()); // 프로젝트 폴더에 저장하기 위해 절대 경로를 설정 String absolutePath = new File("").getAbsolutePath() + "\\"; // 경로를 저장하고 저장한다. String path = "images/" + current_date; File file = new File(path); // 저장할 위치의 디렉토리가 존재하지 않을 경우 if (!file.exists()) { // mkdir() 함수와 다른 점은 상위 디렉토리가 존재하지 않을 때 그것까지 생성 file.mkdirs(); } for (MultipartFile multipartFile : multipartFiles) { // 파일이 비어 있지 않을 때 작업을 시작해야 오류가 나지 않는다. if (!multipartFile.isEmpty()) { // jpeg, png, gif 파일들알 받아서 처리할 예정 String contentType = multipartFile.getContentType(); String originalFileExtension; // 확장자 명이 없으면 잘못된 파일이므로 break 발생 if (ObjectUtils.isEmpty(contentType)) { break; } else { if (contentType.contains("/image/jpeg")) { originalFileExtension = ".jpg"; } else if (contentType.contains("/image/png")) { originalFileExtension = ".png"; } else if (contentType.contains("image/gif")) { originalFileExtension = ".gif"; } else { // 다른 파일 명이면 break 발생 break; } } String newFileName = System.nanoTime() + originalFileExtension; BoardImage boardImage = BoardImage.builder() .originalName(multipartFile.getOriginalFilename()) .imagePath(path + File.separator + newFileName) .fileSize(multipartFile.getSize()) .build(); uploadImagePaths.add(boardImage); file = new File(absolutePath + path + "/" + newFileName); multipartFile.transferTo(file); } } return uploadImagePaths; }
게시글 작성 메서드에 upload 메서드를 사용해서 수정해주었다.
// 게시글 작성 @Transactional @Override public BasicBoard createBasicBoard(User user, BasicBoardRequest request, List<MultipartFile> multipartFiles) throws java.io.IOException { BasicBoard basicBoard = BasicBoard.builder() .content(request.getContent()) .title(request.getTitle()) .boardSort(request.getBoardSort()) .user(user) .build(); List<BoardImage> boardImageList = upload(multipartFiles, basicBoard); // 파일이 존재할 때에만 처리 if (!boardImageList.isEmpty()) { for (BoardImage boardImage : boardImageList) { // 파일을 DB에 저장 basicBoard.addBoardImage(boardImageRepository.save(boardImage)); } } boardRepository.save(basicBoard); return basicBoard; }
포스트맨으로 테스트 해보려고 하면 415 에러가 나오면서 작성이 안된다.
form-data로 키-밸류 값을 잘 준거 같은데 에러가 나온다 ㅠㅠ.. 내일 고쳐봐야겠다..