ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring boot에서 Redirect시 model 변수 값 넘기기
    졸업과제/BackEnd 2023. 3. 31. 20:33

    프로젝트를 진행하다 보니 특정 로직을 동작하고 나면 리다이렉트를 하는 경우의 코드가 상당히 많았다.

    리다이렉트 하는 페이지에는 그냥 html만 뿌려주는 경우는 거의 없고 서버에서 model값으로 전달된 이미지나 데이터를 받아서

    출력하는 경우가 많다.

     

     

    @PostMapping(value = "/post/detailPost/reply")
    public String replyWrite(HttpServletRequest request, Model model, RedirectAttributes attr)
    {
    
        String postId = request.getParameter("p_id");
        long p_id = Long.parseLong(postId);
    
        Post post = postService.findPost(p_id);
        RoomPicture photo = postService.findPhoto(p_id);
        List<Reply> replies = postService.findReply(p_id);
        DetailPostDto detailPostDto = postService.detail_post(post, photo);
        boolean check;
    
        model.addAttribute("post",detailPostDto);
        model.addAttribute("replies",replies);
        model.addAttribute("postId",p_id);
    
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(principal == "anonymousUser"){
            logger.info("[replyWrite] 사용자가 로그인 하지 않아 게시물 작성 불가");
            check = false;
            model.addAttribute("login_inform",false);
            model.addAttribute("reply_msg","로그인 이후 댓글 작성이 가능합니다.");
            model.addAttribute("userId"," ");
            model.addAttribute("check",check);
        }
        else{
            User user = (User)principal;
            logger.info("[replyWrite]  게시물 댓글 작성 로직 동작 postId:{}, userId:{} comment: {}",p_id,user.getUid(),request.getParameter("comment"));
    
            ReplyRequestDto dto = ReplyRequestDto.builder()
                    .postId(p_id)
                    .id(user.getId())
                    .comment(request.getParameter("comment"))
                    .build();
            replyService.Reply_write(dto);
            check = postService.checkFavorite(p_id, user.getId());
    
            model.addAttribute("category", AreaEnum.values());
            model.addAttribute("login_inform",true);
            model.addAttribute("check",check);
            model.addAttribute("userId",user.getUid());
        }
    
    
        return "post/detailPost";
    }

    사용자가 댓글을 작성하면 동작하는 Controller를 예시로 가져왔다.

    내가 잘못 짠 코드 일 수 있지만 코드를 보면  사용자 로그인 정보를 확인하고 로그인이 되었다면 댓글을 DB에 저장하는 코드는 10줄도 되지 않는다. 나머지 코드들은 전부 post/detailPost를 출력할 때 필요한 model값들을 전달해 주는 코드이다.

     

    post/detailPost에서 이미 model로 전달해주고 있는데 이 과정을 댓글 작성 Controller에서 반복하고 있는 것이다.

     

    logout http설정을 해줄때 redirect로 홈화면을 해주었다 그런데 홈 화면에도 여러 가지 model값으로 전달되는 데이터들이 잇는데 redirect를 하니 model 값이 전달되지 않아도 정상적으로 동작하는 것을 보고 redirect로 return 해주면 model 값을 전달하는 

    코드들이 줄어들것 같아 구글에서 조금 찾아보았다.


    Rediect와 Model의 상관관계

    https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=allkanet72&logNo=220964699929 

     

    [스프링] RedirectAttributes

    RedirectAttributes 폼 형식의 문서를 작성 후, 서버로 보내면(POST 방식) 곧이어 다른 페이지로 리...

    blog.naver.com

    블로그를 참고하니 이해가 편했다.

    Model은 Post 방식에 데이터가 실려서 전송된다. 하지만 Redirect는 Get방식인 데다가 아예 새로운 Get요청

    즉 새로고침을 해버리는 것이기 때문에 이전에 전송했던 Model 데이터는 아예 사라져 버리는 것이었다.

     

     

     

     

    그래서 스프링에서는 RedirectAttributes라는 클래스를 제공한다. 이 클래스는 모델의 기능을 확장시킨 것이며

    Redirect를 해도 데이터를 넘겨서 전달해 줄 수 있도록 해준다. 

    방식은 위와 같다. Redirect 직전에 데이터를 session에 저장해 두었다가 Redirect가 되면 Model에 복사를  시킨다.

    이렇게 된다면 Redirect로도 데이터를 전달해 줄 수 있고 특정 페이지를 다시 띄위기 위한 Model 객체들을 

    재전송하지 않아도 된다.

     

    @PostMapping(value = "/post/detailPost/reply")
    public String replyWrite(HttpServletRequest request,RedirectAttributes attr)
    {
        String postId = request.getParameter("p_id");
        long p_id = Long.parseLong(postId);
    
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(principal == "anonymousUser"){
            attr.addFlashAttribute("reply_msg","로그인 이후 댓글 작성이 가능합니다");
        }
        else{
            User user = (User)principal;
            logger.info("[replyWrite]  게시물 댓글 작성 로직 동작 postId:{}, userId:{} comment: {}",p_id,user.getUid(),request.getParameter("comment"));
    
            ReplyRequestDto dto = ReplyRequestDto.builder()
                    .postId(p_id)
                    .id(user.getId())
                    .comment(request.getParameter("comment"))
                    .build();
            replyService.Reply_write(dto);
        }
    
    
        return "redirect:/post/detailPost/"+p_id;
    }

     코드가 절반 가까이는 줄은 것 같다.

    댓글을 작성하고 다시 댓글이 달려 있는 게시물로 리다이렉트 할 경우 필요한 데이터는 

    로그인이 되지 않았을 경우 알림을 보내주는 데이터밖에 존재하지 않는다.

    만약 로그인이 되어있더라면 성공적으로 댓글이 작성되어서 어떠한 데이터도 보내줄 필요가 없다.

     

    addFlashAttribute ( ) 메서드를 이용해 로그인하지 않았을 경우에 알림 팝업에 띄워줄 데이터만 전송하여 줬다.

    사용자가 댓글을 작성했던 게시물로 리다이렉트 할 수 있도록 게시물의 pk를 URL에 추가해서 리다이렉트 하였다.


    Test

     

    로그인하지 않았을 경우 전달됐던 문자가 알림으로 출력되는 모습을 확인된다.

     

     

    댓글

Designed by Tistory.