❗️문제 상황
✉️ 오류 상황
로그인을 시도하여
성공했을 때 alert() 안내문과 함께 Context Path로 리다이렉트가 되도록 의도했었음
하지만 리다이렉트가 되지 않고 현재 페이지에 남아 있음
📃 문제 코드
Servlet 코드
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("action");
if("login".equals(action)) {
HttpSession session = req.getSession();
Object loginId = session.getAttribute("loginId");
if(loginId == null)
req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
else {
req.setAttribute("msg", "이미 로그인 내역이 있습니다.");
req.setAttribute("path", req.getContextPath()); // 맨 첫페이지로 보냄
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
}
} else if ("logout".equals(action)) {
HttpSession session = req.getSession();
session.invalidate(); // removeAttribute("loginId"); 해도 되지만 보통 지금 로그아웃하는 사용자의 정보 싹 날리느라 그냥 세션 객체 자체를 없애버림
req.setAttribute("msg", "로그아웃 되었습니다.");
req.setAttribute("path", req.getContextPath()); // 맨 첫페이지로 보냄
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userid = req.getParameter("userid");
String userpw = req.getParameter("userpw");
if("grepp".equals(userid) && "1234".equals(userpw)) {
HttpSession session = req.getSession(); // 지금 요청보낸 사용자 전용 객체를 찾아낼 수 있음(이전에 나한테 JSessionID 쿠키 발급받아감)
session.setAttribute("loginId", userid);
// 이 부분에서 로그인 성공을 다룸**
**req.setAttribute("msg", "로그인 완료되었습니다.");
System.out.println("경로: " + req.getContextPath());
req.setAttribute("path", req.getContextPath()); // 맨 첫페이지로 보냄
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
} else {
req.setAttribute("msg", "로그인 실패입니다. 아이디나 비밀번호를 확인해주세요.");
req.setAttribute("path", req.getContextPath() + "/user?action=login");
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
}
}
}
// 이 부분에서 로그인 성공을 다룸
req.setAttribute("msg", "로그인 완료되었습니다.");
System.out.println("경로: " + req.getContextPath());
req.setAttribute("path", req.getContextPath()); // 맨 첫페이지로 보냄
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
JSP 코드
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>message</title>
</head>
<body>
<script>
// 해당 부분에서 alert와 함께 context path로 리다이렉션함
alert('<%=request.getAttribute("msg")%>')
location.href = "<%=request.getAttribute("path")%>"
</script>
</body>
</html>
💡 해결 방법
🤔 오류가 발생한 이유
💡 Context Path를 ‘/’로 지정하고 해당 경로(‘/’)로 Redirection해서 생긴 오류였다.
// Servlet
req.setAttribute("path", req.getContextPath()); // 맨 첫페이지로 보냄
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);
// jsp
// 해당 부분에서 alert와 함께 context path로 리다이렉션함
alert('<%=request.getAttribute("msg")%>')
location.href = "<%=request.getAttribute("path")%>"
해당 부분을 자세히보면 req.getContextPath()로 Context Path를 받아와서 해당 경로로 리다이렉트를 하고 있다. 이점이 오류를 발생시킨다.
req.getContextPath()는 Context Path가 ‘/’ 이거나 ‘’(빈 문자열)이면 ‘’(빈 문자열)을 반환한다.
그렇게 되면 리다이렉트시 ‘’(빈 문자열)로 리다이렉트를 한다는 뜻인데, 이는 현재 페이지로 새로고침되는 것과 같다.
🛠️ 수정
1. Application Context Path 수정
근본적인 원인을 처리하는 것이다.
이렇게 특정 문자열을 넣어주면 req.getContextPath()시 빈 문자열이 아니라 해당 경로 그대로 (/root) 반환된다. 그렇게 redirect를 하면 문제가 해결된다.
2. 나는 Application Context Path를 ‘/’로 하고 싶은데?
이 경우엔 Context Path로 리다이렉트를 하는 경우 뒤에 ‘/’만 추가해주면 된다.
// Servlet
req.setAttribute("path", req.getContextPath() + "/"); // 뒤에 '/' 추가
req.getRequestDispatcher("/WEB-INF/views/alert.jsp").forward(req, resp);