컴퓨터과학/Spring

[Spring] 페이지 리로드(새로고침)시 발생하는 데이터 중복전송 현상 방지

waspy 2021. 4. 15. 22:52

문제확인

웹페이지를 이용하다보면 서버에 데이터가 중복으로 전송되는 현상이 발생한다.

예로 로그인 실패 직후 새로고침을 하면 이전에 진행된 데이터 전송 프로세스가 반복돼서 실행되며 이로인해 불필요한 연산이 진행되고, 뷰로 로그인 실패에 관한 정보를 다시 전송하게된다.

(로그인 실패 → 잘못된 아이디 입력 alert표시 → 새로고침 → 다시 잘못된 아이디 입력 alert ... )

 

원리

이러한 현상을 어떻게 방지할지 고민하다가 새로고침시 호출되는 컨트롤러(핸들러)는 최종으로 리다이렉트된 컨트롤러을 알게되었고, 이 작동방식을 이용해 문제를 해결하였다.

 

실행

이를 위해선 최초 데이터 수신 컨트롤러와 리다이렉트 이후 뷰로 데이터를 전송하는 컨트롤러를 구분하였다.

 

1. 데이터 수신 컨트롤러

@PostMapping("/login")
    public String login(@RequestParam String email, @RequestParam String pw, RedirectAttributes rttr){
        log.info("second called");
        UserVO vo = userService.get(email);
        if(vo == null){ // 아이디 없음
            rttr.addFlashAttribute("loginTry","false");
            rttr.addFlashAttribute("loginMsg","존재하지 않는 아이디입니다.");
            return "redirect:/user/login";
        }else{
            if(!vo.getPw().equals(pw)){ // 비밀번호 불일치
                rttr.addFlashAttribute("loginTry","false");
                rttr.addFlashAttribute("loginMsg","잘못된 비밀번호입니다.");
                return "redirect:/user/login";
            }else{ //로그인 성공
                session.setAttribute("user", vo);
                rttr.addFlashAttribute("loginTry","true");
                return "/index";
            }
        }
    }

 

2. 뷰로 데이터를 전송하는 컨트롤러

@GetMapping("/login")
    public String login(Model model, String loginTry, String loginMsg){ // send message to login page
        if(loginTry == null)
            return "/login";
        if(loginTry.equals("false")){
            model.addAttribute("loginTry", false);
            model.addAttribute("loginMsg",loginMsg);
        }else{
            model.addAttribute("loginTry", true);
        }
        return "/login";
    }

 

1번 컨트롤러에서 데이터 수신, 로그인service를 통해 로그인 성공 여부를 판정 한 뒤 LoginTry 정보를 RedirectAttributes 에 담아 2번 컨트롤러로 리다이렉트 한다.

그 다음 alert에 담을 내용 (loginMsg) 을 2번 컨트롤러에서 model에 담아 view로 전송한다.

 

이렇게되면 새로고침시 1번 컨트롤러 호출 없이 2번컨트롤러를 호출하게 되며, loginMsg에 아무 내용이 담기지 않은채로 뷰를 브라우저에 전송함으로써 프론트 js에서 loginMsg가 없음을 확인하고 중복해서 alert하는 현상을 방지할 수 있게된다.

 

반응형