강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

hwanghsp님의 프로필 이미지
hwanghsp

작성한 질문수

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

타임리프

작성

·

223

1

타임리프를 배우고 웹 개발시 header.html, footer.html을 나눠서 작성하고 있습니다.

예를 들어 유저의 개인정보를 변경하는 페이지(profile.html)는 관련 Contoller에서 user의 id를 넘겨서 뿌려줘서 잘 작동하는데

문제는 header.html에서 사용하는 user의 id입니다.
예를 들어header.html에 메뉴바가 있어서 해당 아이콘을 누르면 user의 id를 실어서 profile.html로 넘어가게끔 해야하는데 id를 어디서 받아와야하는지 모르겠습니다.

Controller

@Controller
public class BasicController {

    @GetMapping("/layout/header")
    public String userInfo(@AuthenticationPrincipal PrincipalDetails principalDetails, Model model) {
        model.addAttribute("user.", "principalDetails.getUser()");
        return "layout/header";
    }
}
<nav class="navi">
   <ul class="navi-list">
      <li class="navi-item"> <a th:href="@{/user/{id}(id = ${user.id})}"></a></li>
   </ul>
</nav>

 [[ 에러내용은 ]]

Exception evaluating SpringEL expression: "user.id" (template: "/layout/header" - line 43, col 32)

Property or field 'id' cannot be found on null

 

 

코드를 어떻게 작성해야하는지 모르겠습니다. 아래와 같은 방법으로도 안 되어서 갈피를 못 잡겠습니다.

<a th:href="'/user/' + ${user.id}">

답변 1

2

안녕하세요. hwanghsp님, 공식 서포터즈 David입니다.

모델 속성의 key로 'user.' (점 포함)을 작성하셨는데 .(점)을 빼보시고 다시 시도해보시겠어요?

감사합니다.

hwanghsp님의 프로필 이미지
hwanghsp
질문자

답변감사합니다, 해당 부분은 제가 글을 올리는 과정에서 오타였습니다,,;;

profile을 호출하는 핸들러에서 model에 user id를 담으시면 header fragment 내에서 불러올 수 있는데 한 번 해보시겠어요?

hwanghsp님의 프로필 이미지
hwanghsp
질문자

profile.html을 호출하는 핸들러에 (header.html와 profile.html에 쓰일) 세션(principalDetails.getUser())을 담아서 보냈습니다. (다른 곳에서 세션id는 principalDetails.getUser().getId() 하면 나왔습니다 )

  • 보낼 때 principalDetails.getUser().getId() 이렇게도 해봤는데 안되었습니다.

@RequiredArgsConstructor
@Controller
public class UserController {

    private final UserService userService;

    @GetMapping("/user/{pageUserId}")
    public String popular(@PathVariable int pageUserId, Model model, @AuthenticationPrincipal PrincipalDetails principalDetails) {
       
        model.addAttribute("principal", principalDetails.getUser());


        return "/user/profile";
    }

 

 

그후 이제 .html에서 가져다 써야 하는데

다른 것들은 다 불러 왔는데 id가 안들어가네요, 말씀주신 [header fragment 내 불러올 수 있는 방법] 알 수 있을까요?

 

header.html

<nav th:object="${principal}"> 이렇게도 해봤는데 안됩니다.

id를 써야될 부분은)

<a th:href="@{/user/{id}(id = ${principal?.id})}">
<!DOCTYPE html>
<html th:fragment="header" xmlns:th="http://www.thymeleaf.org"  >

<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title></title>
</head>

<body>
   <header class="header">
      <div class="container">
         <a th:href="@{/image/story}" class="logo">
            <img th:src="@{/images/logo.png}" alt="">
         </a>
         <nav class="navi">
            <ul class="navi-list">
               <li class="navi-item"><a th:href="@{/image/story}">
                     <i class="fas fa-home"></i>
                  </a></li>
               <li class="navi-item"><a th:href="@{/image/popular}">
                     <i class="far fa-compass"></i>
                  </a></li>
               <li class="navi-item"><a th:href="@{/user/{id}(id = ${principal?.id})}">
                     <i class="far fa-user"></i>
                  </a></li>
            </ul>
         </nav>
      </div>
   </header>
</body>

</html>

컨트롤러 내에서 해당 id가 정상적으로 찍히는지 확인해주실 수 있으실까요?

hwanghsp님의 프로필 이미지
hwanghsp
질문자

지금 header.html에 profile.html은 무조건 1로 가게 해둬서 다른 id로 로그인시 에러발생합니다.

<li class="navi-item"><a th:href="@{/user/1}">

image

 

해당 컨트롤러 내에서 이렇게 찍어보았을 때 콘솔 내용 입니다.

System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("dto: " + dto);
System.out.println("principalId: " + principalDetails.getUser().getId());
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++");

 

콘솔

image

 

해당 User.java:17과 Image.java:18은 도메인 위의 @Data 입니다.

NPE가 발생하는걸로 보아서는 사용자 정보를 정상적으로 불러오지 못한 걸로 보여지는데, 이 부분을 해결해보시겠어요?

hwanghsp님의 프로필 이미지
hwanghsp
질문자

현재 profile을 호출하는 핸들러에서 model에 user id를 담았더니 profile.html에서 사용가능함을 확인했습니다. (로그인한 아이디 : principalDetails.getUser().getId())

Controller

model.addAttribute("principalId",  principalDetails.getUser().getId());
        return "/user/profile";

 

profile.html

<button th:onclick="'profileImageUpload(' + ${dto.user.id} + ', ' + ${principalId} + ')'">사진 업로드</button>

 

여기서 어떻게 하면 header fragment 내에서 불러와서 쓸 수있나요?

hwanghsp님의 프로필 이미지
hwanghsp

작성한 질문수

질문하기