[ Spring / SW 캠프] 회원정보 보기

김문경·2023년 11월 16일
0

SW 백엔드 캠프

목록 보기
1/4
  • review (로그인)
    이전 주차에서는 회원가입 및 로그인을 진행.
    회원가입한 user의 data를 h2-database에 저장까지 완료

  • preview (회원정보 보기)
    preview




Server-side rendering (회원정보 보기)

DB에 저장되어 있을 로그인 정보를 가져와서 회원정보 페이지에 뿌리려고 합니다.

Spring에서 사용하는 기본 전략인 MVC 패턴에서 이번에는 ControllerServiceRepository 이 세 파트를 주력으로 설명하겠습니다.




- UserController

 // start of UserController
 
@PostMapping("/login")
public String login(@Valid UserRequest.LoginDTO requestDTO, Errors errors) {
        User sessionUser = userService.로그인(requestDTO);
        session.setAttribute("sessionUser", sessionUser); // #1. session 저장소에 User 객체 저장
        return "redirect:/";
 }
 
 
  @GetMapping("/user/updateForm") 
  public String updateForm(HttpServletRequest request) {
        User sessionUser = (User) session.getAttribute("sessionUser"); //#2-1
        UserResponse.DTO responseDTO =  userService.회원정보폼보기(sessionUser.getId()); #2-2
        request.setAttribute("user", responseDTO);
        return "user/updateForm";
    } //#2. server-side 렌더링

 
 // end of UserController

🥕#1. session 저장소에 User 객체 저장

이전에 login 페이지를 작성할 때, sessionUser 객체를 저장해 두었습니다.
session에 저장해 둔 값은 언제든 가져올 수 있는 값이기에 회원정보를 조회하기 위해서 user의 id와 name, email 값을 가져오려 합니다.

🥕#2. server-side 렌더링

updateForm을 호출할 때, HttpServletRequest request를 받아옵니다.
화면이 redirect 되는것이 아닌, server 안에서 내부적으로 리렌더링 된 후 완성된 값을 가져오는 것이라 정보의 손실없이 전달 가능합니다.

server에서 모든 정보를 처리한 뒤 완전한 페이지를 return 한다고 하여 Server-side Rendering 이라고 합니다.
* redirect : request 요청이 2번 일어나기에 중간에서 전달하고자 하는 정보가 손실될 수 있습니다.

  • 🥬 #2-1
    seeion에 저장되어있는 User 객체를 받아오는 코드입니다.
    getAttribute의 return type은 Object로 받아오는데 session에 들어가있는 타입을 미리 알 수 없으니 부모인 Object로 받아와서 사용할 자식 객체로 downCasting 하여 사용하라는 의미입니다.

  • 🥬 #2-2
    controller → Service로 session에 저장되어있는 User의 id를 넘깁니다.










- UserService

//start of UserService

public UserResponse.DTO 회원정보폼보기(Integer id) {
        User userPS = userRepository.findById(id) //#1 Service → Repository
                .orElseThrow(() -> new Exception404("해당 아이디로 자원을 찾을 수 없습니다. " +id));
        return new UserResponse.DTO(userPS);
    }
    
//end of UserService

🥕 #1. Service → Repository로 id 값을 넘기는 과정입니다,










-UserRepository

//start of UserRepository 

//SELECT * FROM USER_TB WHERE ID=1 

//end of UserRepository


🥕#0. findById()

Service에서 사용된 findById()는 JPA에 내장되어 있는 메서드입니다.
따라서 구현을 할 필요가 없어 코드를 첨부하지 않았습니다

findById()는 나와있는 글자 그대로 Id 값을 기준으로 Database에서 값을 찾는 메서드입니다.
→ 여기서는 id값으로 Database에 들어가있는 user 정보를 가져오는 역할을 합니다.










-UserService

//start of UserService

public UserResponse.DTO 회원정보폼보기(Integer id) {
        User userPS = userRepository.findById(id)
                .orElseThrow(() -> new Exception404("해당 아이디로 자원을 찾을 수 없습니다. " +id)); 
		//#1.retrun type : Optional
        
        return new UserResponse.DTO(userPS); //#1-1 응답 DTO
    }
    
//end of UserService


//start of UserResponse (UserService에서 사용되는 class)

public class UserResponse { //#1-1 응답 DTO

    @Data // getter, setter 생성
    public static  class  DTO {
        private int id;
        private String username;
        private String email;

        public DTO(User user) {
            this.id = user.getId();
            this.username = user.getUsername();
            this.email = user.getEmail();
        }
    }
}

//end of UserResponse

🥕 #1. retrun type : Optional< T >

앞전 포스팅에서 설명했던 Optional과 lamda 함수에 대한 적용입니다.
findById의 return 타입은 Optional< T > 입니다.
Repository를 통해 DB에서 id를 가진 User를 조회하지만, 값이 존재하지 않는 경우, null값이 UserPS에 담길 수 있습니다.

이때 null값도 허용하여 선물박스 안에 담는 Optional 객체를 사용하여 받아온 뒤 .orElseThrow 라는 메서드를 통해 만약 값이 null이라면 exception404를 터트리고, 그렇지 않다면 user의 값이 userPS에 담길 것입니다.

  • 🥬#1-1 응답 DTO
    주로 service의 역할은 트랜젝션 관리, 비지니스 플랜 등의 역할을 하지만 저는 추가적으로 응답 DTO생성 (UserResponse) 까지 포함하여 작성하였습니다.

  • 🥬 Q. 응답 DTO의 생성 - why?
    A. 회원정보 보기를 진행할 때에 필요한 User정보는 id와 username, email 입니다.
    이 외의 불필요한 정보를 (ex Password) User객체에 그대로 담아서 보내게 된다면 FrontEnd에서 해당 DTO를 받게 되었을 때, 착오가 생길 수 있습니다.










-UserController

 // start of UserController
 
  @GetMapping("/user/updateForm") 
  public String updateForm(HttpServletRequest request) {
        User sessionUser = (User) session.getAttribute("sessionUser"); 
        UserResponse.DTO responseDTO =  userService.회원정보폼보기(sessionUser.getId()); 
        //#1 Service로부터 받아온 responseDTO 저장
        request.setAttribute("user", responseDTO); //#2. session에 정보저장
        return "user/updateForm";
    } 
 // end of UserController

🥕 #1. Service로부터 받아온 responseDTO 저장
UserService에서도 언급을 했듯, DB에서 가져온 User를 그대로 가져와도 되지만 resPonseDTO에 필요한 User의 값들만 담아 Controller로 가져왔습니다.

🥕#2. session에 정보저장
session 메모리 영역에 'user'라는 key값으로 userid, username, email이 담겨있습니다.

`updateForm`을 호출한 뒤 Controller, Service, Repository를 거쳐 생성된 user의 정보를 가지고 `updateForm`을 다시 재호출 하는 과정이 Server-Side Rendering입니다.
(서버측에서 모든 정보를 처리한 후 return 하는것)





-UpdateForm.mustache

<form action="/user/update" method="post">
	<div class="mb-3">
		<input type="text" class="form-control" placeholder="Enter username" disabled value="{{user.username}}">
	</div>
	<div class="mb-3">
		<input type="password" class="form-control" placeholder="Enter password" name="password">
	</div>
	<div class="mb-3">
		<input type="email" class="form-control" placeholder="Enter email" disabled value="{{user.email}}">
	</div>
	<button type="submit" class="btn btn-primary form-control">회원가입수정</button>
</form>
  • 🥕실제 updatefrom을 호출했을 때 불려오는 mustache 파일입니다.
    Controller에서 session에 user key값으로 저장한 useremail과 username을 value="{{user.username}}" , value="{{user.email}}" 과 같은 방식으로 가져옵니다.










이렇게 하면 최종적으로 아래와 같이 현재 로그인한 사람의 정보를 들고와 회원정보를 열람하는것이 가능합니다.
preview

🥕FIN🥕

0개의 댓글