ㅁ 앞으로의 활용 과정
- request 객체에서 데이터를 뽑고 난 이후에, 이 뽑은 데이터를 DB에 기록한다고 하면.
- data를 service를 호출하면서 넘기고, service에서는 dao로 넘기고, dao에서 insert문 때려서 그 결과를 돌려받는다.
(jdbc과정)
- 성공적으로 다 되었다면 응답페이지를 제작해서 돌려줘야 한다.
요청에 대한 결과 페이지를 사용자에게 보여줘야한다.
ㅁ 응답페이지
- 아래처럼 index.html을 작성한다.
- 아래처럼 c_response라는 폴더 안에 main.html 만든다.
- 화면단만 바꿨기 때문에 서버를 재시작할 필요는 없다.
브라우저만 다시 새로고침하고 3을 누르면.
- 이렇게 뜬다.
ㅁ main.html에 아래와 같이 더 작성.
ㅁ 이클립스에서 c_resonse.Response <- 서블릿클래스 만들기
- src/main/java 안에 c_response라는 패키지를 만들고 Response라는 서블릿 클래스를 만듦.
- 그리고 @WebServlet("/Response")를 @WebServlet("/response")로 바꿈.
- URL mapping을 하는 2번째 방법. 둘 중 하나만 쓰면 됨. web.xml에 쓰면 한 눈에 볼 수 있는 장점이 있지만 작성하는것 자체가 좀 복잡하다.
annotaion 방식은 단순하게 작성할 수 있지만, 어떤 url 요청시 어떤 servlet이 실행되는지는 일일이 servlet을 까봐야 안다.
- 만약 어노테이션 방식을 쓰지 않고 web.xml 파일을 수정하는 식으로 하겠다면,
- 이런 상태인데 아래와 같이 수정.
ㅁ Response.java 에서 어노테이션을 R에서 r로 바꾸고 주석처리만 했다.
package c_response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// @WebServlet("/response") 이번엔 xml 방식으로 해본다.
public class Response extends HttpServlet {
private static final long serialVersionUID = 1L;
public Response() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- doPost 메소드의 이미 쓰여져 있는 코드를 보면, 다시 doGet 메소드를 호출하고 있다.
get방식 요청이든 post방식 요청이든 그냥 편하게 doGet 메소드에서 작업하라고 해놨다.
- 참고로 doGet 메소드의 원래 있던 코드는 지워주는게 좋다.
ㅁ < HttpServletResponse >
- 요청을 보낸 클라이언트에게 응답할 수 있는 객체
- doGet() 또는 doPost() 메소드 실행시 해당 객체가 생성되어 매개변수(response)에 전달
- 응답 관련 주요 메소드
1) getWriter() : 클라이언트에게 응답문자를 전송할 수 있는 출력 스트림(PrintWriter 타입) 반환
2) setContentType(String) : 응답문자의 데이터 형식(MIME-TYPE)을 설정
3) sendRedirect(String) : 리다이렉트할 URL 전송
- getWriter()는 통로다. 응답 데이터를 전달하려면 클라이언트와 연결된 통로가 필요하다.
출력 스트림을 통해 클라이언트에게 응답 데이터를 전달한다.
- ContentType이라고도 하고 MIME-TYPE이라고도 한다. 문자의 유형. 데이터 형식.
- 3)은 나중에 Redirect할 때 따로 배운다.
ㅁ 응답 데이터 형식 3단계
- 응답 Content-type 설정 + UTF-8 인코딩
1) HTML : text/html
2) XML : application/xml
3) JSON : application/json
- 지금은 응답 페이지를 돌려주기 때문에 HTML을 돌려준다. 그러면 text/html을 쓴다.
- xml을 돌려주는 일은 거의 없을 거고, html 아니면 json을 돌려줄건데 json은 나중에 ajax 배울때 함.
ㅁ Response.java
package c_response;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// @WebServlet("/response") // 이번엔 xml 방식으로 해본다.
public class Response extends HttpServlet {
private static final long serialVersionUID = 1L;
public Response() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); // 소문자로 작성해도 상관 없다.
String userId = request.getParameter("userId"); // 오른쪽 userId는 key값 그대로 써야 함. 왼쪽 변수명은 맘대로 가능.
String userPwd = request.getParameter("userPwd");
// 요청시 전달하는 값을 service로 넘기고 service는 dao로 넘기고 dao에서 쿼리 실행 후 결과 받음 (컨트롤러 입장)
// select 쿼리 실행했다 침. 성공적으로 조회되었다는 가정 하에 응답페이지를 제작 후 출력한다.(로그인)
// 1. 응답 문자의 데이터 형식 지정. (Content-type 설정 + UTF-8 인코딩)
response.setContentType("text/html; charset=utf-8"); // 하나의 문자열이라 세미콜론으로 구분.
// 2. 응답할 출력 스트림 알아내기
PrintWriter out = response.getWriter(); // 빨간줄 안 뜸. 예외처리 throws로 하고 있음.
// 3. 응답문자 전송 (출력 스트림을 통해 html을 출력)
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("<title>로그인성공페이지</title>");
out.println("</head>");
out.println("<body>");
out.println("<script>alert('반갑습니다');</script>");
out.println("<h1>반갑습니다 회원님!" + userId + "계정으로 로그인 성공입니다.</h1>");
out.println("</body>");
out.println("</html>");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- post 방식 요청도 doGet 메소드에 작성을 해놓아도 된다.
- [오류발생. 11시 40분]
이런게 뜸. 어노테이션과 web.xml에서 둘다 /response를 해서 그럼.
근데 주석을 없애고 클린하고 재시작해도 계속 저렇게 뜸.
web.xml을 날려버리고 어노테이션 방식으로 하니까 됨.
- alert가 먼저 뜨고 위와 같은 응답 화면이 뜬다.
- 브라우저 측에서 얘를 html구문으로 인식해서 사용자에게 시각적으로 보여준다.
- 요청시 전달된 데이터로 요청을 처리하고, 그에 대한 응답 페이지를 이렇게 자바단에서 제작을해서 출력을 시켜주는게 서블릿의 역할입니다.
- 지금 화면 구현을 자바코드 작성하는 곳에서 진행하고 있다.
지금은 그나마 간단한 페이지라서 코드가 얼마 안되지만 코드가 긴 페이지면 굉장히 복잡해진다.
- 그래서 이런 불편함을 개선해서 나온게 JSP다. 나중에 JSP 배우면 응답페이지 제작 과정을 JSP에 위임함.
================================================================================
ㅁ 이제 4. Forward
- src/main/webapp 폴더에 d_forward 폴더를 만들고, d_forward 폴더 안에 main.html 만든다.
- 아래는 d_forward 폴더의 main.html 이다.
- 아래는 webapp 폴더의 index.html이다.
여기서 4를 누르면
이렇게 잘 되는지 확인해봤다.
ㅁ 서블릿 클래스 생성
- d_forward.FirstStep, d_forward.SecondStep
- src/main/java에 d_forward 패키지를 만든다.
d_forward 패키지에 FirstStep 서블릿과 SecondStep 서블릿을 만든다.
- 아래는 d_forward 폴더의 main.html 이다.
- /first라는 url 매핑값의 서블릿을 호출하고 있다.
- 아래는 FirstStep.java 서블릿 클래스다.
package d_forward;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/first") // http://localhost:8888/servlet/first라는 URL 요청시 실행될 서블릿
public class FirstStep extends HttpServlet {
private static final long serialVersionUID = 1L;
public FirstStep() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("첫번째 목적지(경유지) 도착");
// forward라는 기술을 사용해서 서블릿에서 서블릿으로 이동할 수 있다.
request.getRequestDispatcher("/second").forward(request, response); // contextPath 빼고 url mapping만 작성하면 된다.
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- 포워드 하는 구문 (url mapping만 이동할경로에 작성하면 된다)
request.getRequestDispatcher("이동할경로").forward(request, response);
- 아래는 SecondStep.java
package d_forward;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/second") // http://localhost:8888/servlet/second라는 URL 요청시 실행될 서블릿
public class SecondStep extends HttpServlet {
private static final long serialVersionUID = 1L;
public SecondStep() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("두번째 목적지(도착지) 도착");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
링크 누르면
이렇게 이동.
- 주소창 링크는 첫번째 목적지 주소만 노출되었다.
이클립스에는 이렇게 출력됨.
ㅁ 첫번째 목적지에서 포워딩시 request, response를 두번째 도착지로 전달했다.
- 그래서 각각 doGet 메소드에 대입되어있다.
- 첫번째 목적지에서 넘어온 파라미터를 두번째 서블릿의 doGet 메소드에서 고스란히 꺼낼 수 있다.
- 아래는 d_forward 폴더의 main.html 이다.
- 이건 get방식이라 doGet 메소드만 호출됨.
- forward는 요청의 방식을 유지하므로, GET이든 POST든 원래 요청된 방식을 그대로 사용합니다.
- 데이터를 전달하면서 요청을 보내본다.
- 아래는 SecondStep.java
package d_forward;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/second") // http://localhost:8888/servlet/second라는 URL 요청시 실행될 서블릿
public class SecondStep extends HttpServlet {
private static final long serialVersionUID = 1L;
public SecondStep() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("두번째 목적지(도착지) 도착");
//첫번째 목적지에서 포워딩시 request, response를 두번째 도착지로 전달했다.
//그래서 각각 doGet 메소드에 대입되어있다.
//첫번째 목적지에서 넘어온 파라미터를 두번째 서블릿의 doGet 메소드에서 고스란히 꺼낼 수 있다.
System.out.println("param(name) : " + request.getParameter("name"));
System.out.println("param(age) : " + request.getParameter("age"));
// 응답
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('최종 목적지 도착!');");
out.println("</script>");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- alert만 띄우는 것은 스크립트만 돌려줘도 잘 작동된다.
자바스크립트는 HTML과 독립적으로 실행될 수 있습니다.
HTML 문서가 자바스크립트를 로드하고 실행하는 구조를 제공할 뿐,
자바스크립트 자체는 특정 HTML 태그에 종속되지 않습니다.
- 새로고침하고 누르면
- alert가 뜨고 빈 화면이다.
- 최종적으로는 second라는 url 요청이 되어서 SecondStep이 실행되고 있는데
url에는 a태그에 작성한 링크만 노출된다. first만 보이고 second는 보이지 않는다.
forward로 이동한 경로(second)는 보이지 않는다.
- 지금은 서블릿에서 서블릿으로 이동했지만, 나중엔 서블릿에서 JSP로 이동할 것이다.
ㅁ 서블릿이 실행되는 경우 3가지
(1) 클라이언트 요청에 의해서 (a, form submit 등)
(2) 서블릿에서 또다른 서블릿으로 "이동"할 경우 (forward)
(3) 서블릿에서 또다른 서블릿을 "재호출"할 경우 (redirect) <- url을 다시 강제로 호출
ㅁ < forward >
- 특정 처리를 대신할 Servlet 및 JSP로 이동시 사용하는 기술
주로 응답페이지 제작하는 과정을 JSP에게 위임할 때 사용할 예정
- 포워딩시 현재 서블릿에서 생성된 request, response 객체를 전달해야 한다.
이동된 곳에서 해당 request, response를 그대로 사용할 수 있다.
- 이동 경로 작성시 contextPath를 제외하고 작성.
서블릿으로 이동하고 싶으면 url 매핑값만,
특정 페이지로 이동하고 싶으면 contextPath를 제외한 나머지 페이지의 경로만 작성.
- ★★★ URL에는 forward된(이동된) 경로가 노출되지 않는다. ★★★
이게 포워드의 중요한 특징이다.
클라이언트는 이동된 경로를 확인할 수 없다. 클라이언트에게 이동한 경로를 숨길 수 있다.
클라이언트에게는 최초 요청했던 URL만 보여진다.
- 주로 forward 하는 경우
1) 단순히 페이지 이동할 때
- 경로작성해서 그냥 이동해도 되지만 url이 노출되니까 보안상 위험해서 이동한 경로를 숨기고자 할 때.
- 그냥 링크로 이동해도 되는데, 서블릿을 호출해서, 거기서 포워드 메소드로 페이지로 이동.
2) select 쿼리 이후
- 조회 이후 forward를 굉장히 자주한다. db로부터 데이터를 조회 후 페이지로 이동할 때 forward 한다.
=========================================================================
ㅁ 5. Redirect
- 아래는 index.html이다.
- <a href="/servlet/e_redirect/main.html"> 이런게 단순 페이지 이동이다.
- e_redirect 폴더에 main.html 파일을 아래와 같이 만든다.
- 이페이지가 잘 뜨는지 확인부터 한다.
- 5.Redirect를 누르면
- 잘 뜬다.
ㅁ forward 해야 하는 경우 1
- db로부터 데이터 조회 후 페이지로 이동해야될 때
- 아래는 main.html이다
- 'list.bo'가 게시글 전체 조회 요청하는 URL Mapping 값이다.
- '게시글 전체 조회'를 클릭하는 순간 게시글 전체 조회 데이터가 보여지는 정적 페이지로 곧바로 이동할 수 없다.
db에서 데이터를 조회해야하는데 db 데이터 조회를 서블릿에서 하니까 무조건 서블릿을 호출해야 한다.
- db로부터 데이터 조회해서 그 조회된 데이터로 페이지를 구성해야 할 때 서블릿을 호출해야만 한다.
- src/main/java에 e_redirect 패키지를 만들고 BoardList.java라는 서블릿을 아래처럼 만든다.
package e_redirect;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/list.bo")
public class BoardList extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardList() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("게시글 전체 조회용 Servlet 실행 (JDBC과정을 통해 필요 데이터 select 진행)");
// => service => dao => 게시글 전체 데이터 select 쿼리 실행 (JDBC)
// 위와 같이 조회된 데이터를 가지고 응답페이지 제작
// 위의 과정이 성공적으로 수행됐다는 가정 하에 응답페이지 : /servlet/e_redirect/boardList.html (html로 작성후 포워딩해서 띄운다.)
request.getRequestDispatcher("/e_redirect/BoardList.html").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- 아까처럼 response 객체를 이용해서 한땀한땀 사용자에게 응답페이지를 보여줄 수도 있지만,
너무 번거롭기 때문에 나중에 JSP 배우면 응답 페이지 제작 과정은 JSP에게 위임한다.
- 사용자에게는 boardList.html 페이지가 보여지지만 url에 보여지진 않는다. 처음 요청 url만 보여진다.
forward는 이동경로가 노출되지 않는다.
- e_redirect 폴더 안에 boardList.html을 아래처럼 만든다.
- 누르면
- 이렇게 잘 뜬다.
- url에는 boardList.html이라고는 뜨지 않는다. 최초 요청한 list.bo만 노출된다.
forward 방식으로 이동한 경로는 url에 노출되지 않는다.
- 이클립스 콘솔에도 이렇게 뜬다.
- 404 오류가 뜨는 이유는 서블릿을 못 찾을 거나 이동할 경로(html 페이지)를 못찾는 경우다.
대부분 오타다. 특히 대소문자.
서블릿 annotation과 포워드 메소드 getRequestDispatcher(이동할경로)에 오타가 없는지 체크한다.
ㅁ boardList.html의 '게시글 작성' 버튼 클릭시 보여줄 페이지를 만든다.
- 게시글 작성 페이지는 db로부터 뭔가 조회할 필요가 없는 페이지다.
그냥 텍스트 상자 두 개가 끝이다. 그냥 정적인 페이지다.
- 아래는 webapp/e_redirect 폴더의 boardWrite.html이다.
- 아래는 e_redirect 폴더의 boardList.html이다.
- button은 a 태그가 아니라서 href 속성을 사용할 수 없다. 이벤트 핸들러를 연결한다.
- location.href는 현재 페이지의 URL을 설정하는 속성입니다.
이 속성에 새로운 URL을 할당하면, 웹 브라우저는 해당 URL로 페이지를 이동합니다.
- 게시글 작성 페이지는 db로부터 조회해올 데이터가 없으므로 그냥 정적 페이지 이동을 할 수 있다.
서블릿을 거치지 않아도 된다.
- 새로고침하고 눌러보면 아래와 같이 뜬다.
- 그런데 url에 다 노출이 된다. 보안에 문제가 있다.
프로젝트의 디렉토리 구조가 외부에 노출되면 무작위 공격이 들어올 수 있다.
- 그래서 db로부터 조회할 데이터 없는 단순 페이지 이동이라하더라도 서블릿을 호출해서 포워딩 방식으로 이동하는게 제일 좋다.
ㅁ forward 해야 하는 경우 2
- 정적페이지(DB로부터 데이터를 조회할 필요가 없는) 이동시 이동할 경로를 URL로부터 숨기고자 할 때
이럴 때도 서블릿을 호출해서 그 서블릿에서 포워딩을 통해서 페이지를 이동하는 것이 좋다.
- 아래는 boardList.html이다.
- src/main/java에 e_redirect 패키지에 BoardWriteForm이라는 서블릿 클래스를 만들고 주석으로 /writeForm.bo를 준다.
package e_redirect;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/writeForm.bo")
public class BoardWriteForm extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardWriteForm() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("게시글 작성 페이지 이동용 Servlet 실행 (JDBC 과정 없이 바로 페이지 이동)");
// 응답페이지 : /servlet/e_redirect/boardWrite.html
request.getRequestDispatcher("/e_redirect/boardWrite.html").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- '게시글 작성' 버튼에 이벤트 핸들러를 연결해서, 그냥 바로 정적인 페이지로 이동하면 경로가 노출되니까 그렇지 않게끔, servlet을 호출해서 forward로 정적인 페이지로 이동했다.
- 이 서블릿에서 forward로 이동!!
- jdbc 과정 없이 그냥 페이지 이동만 있는 서블릿 클래스다.
- '게시글 작성' 버튼을 클릭하면 아래와 같이 뜬다.
- 똑같이 뜨는데 아까와 경로가 다르다.
boardWrite.html이 노출되지 않고 처음 요청 보냈던 서블릿 url mapping 값(wirteForm.bo)만 보여진다.
- '게시글 전체 리스트'가 뜨면 첫째줄 나옴.
- '게시글 작성 페이지'가 뜨면 두번째줄 나옴.
=======================================================================
ㅁ Redirect
- 이제 등록하기 버튼 누르면 redirect 할 예정이다.
- /servlet/list.bo 요청시 => 페이지1 (전체게시글 조회 페이지 = boardList.html)
- /servlet/writeForm.bo 요청시 => 페이지2 (게시글 작성 페이지 = boardWrite.html)
- 각각 페이지로 이동할 때 바로 이동하지 않고 서블릿을 거쳐서 이동했다.
- 이제 게시글 작성 페이지에서 '등록하기' 버튼을 누르면 사용자가 입력한 데이터가 db에 insert 되게 할 것이다
- 아래는 boardWrite.html이다.
- 매핑값이 insert.bo라는 서블릿 클래스가 필요하다.
- 이클립스에서 e_redirect 폴더 안에 BoardInsert 서블릿 클래스를 만든다.
package e_redirect;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/insert.bo")
public class BoardInsert extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardInsert() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("게시글 등록 요청용 Servlet 실행 (JDBC 과정을 통해 데이터 insert 진행)");
// 요청시 전달된 값을 뽑아서 각 변수에 기록
request.setCharacterEncoding("UTF-8");
String title = request.getParameter("title");
String content = request.getParameter("content");
// 원래대로라면 이제 service 호출하고 dao 호출해서 게시글 데이터 insert 쿼리를 진행한다.
// 그리고 그 결과를 돌려받고 성공적으로 추가되었다는 가정 하에
// 응답페이지 : 다시 게시글 전체 조회 페이지로 이동(단, 새로 추가된 데이터도 조회돼서 보여야 한다.)
request.getRequestDispatcher("/e_redirect/boardList.html").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- post방식 이라 post 메소드가 호출되었다가 doGet 메소드가 호출된다.
- 여기에 제목1, 내용1을 입력하고 등록하기 한다. (빨간 밑줄은 재사용한 거임. 신경 ㄴㄴ)
- 다시 이 페이지로 돌아온다.
- 그런데 이건 잘못된 방식이다. 전체 리스트 화면에는 항상 list.bo가 찍혀있어야 하는데 insert.bo가 찍혀있다.
db에 insert는 했지만, 조회하는 과정은 진행하지 않았다.
문제점1. 포워딩을 통해 해당 페이지가 보여지긴 하나 여전히 /servlet/insert.bo가 노출되어 있음.
문제점2. 새로 추가된 데이터를 다시 조회해서 뿌려야만 하는데 새로이 조회가 진행되지 않음.
- forward 방식은 서버 내부에서만 요청을 전달하기 때문에, 클라이언트의 새 요청이 발생하지 않습니다.
- 이 경우, 전달된 요청에 대한 서버의 응답도 기존 요청의 응답 흐름을 따르기 때문에 데이터가 업데이트되었더라도 새로운 요청을 통해 갱신된 데이터를 조회하지 않습니다.
- 전체게시글 조회페이지는 /servlet/list.bo가 찍혀있어야 한다. 다른 url은 안 된다.
게시글 작성페이지는 /servlet/writeForm.bo가 찍혀있어야 한다.
ㅁ Redirect (재호출 = 재요청)
- 아래는 BoardInsert.java다.
package e_redirect;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/insert.bo")
public class BoardInsert extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardInsert() { super(); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("게시글 등록 요청용 Servlet 실행 (JDBC 과정을 통해 데이터 insert 진행)");
// 요청시 전달된 값을 뽑아서 각 변수에 기록
request.setCharacterEncoding("UTF-8");
String title = request.getParameter("title");
String content = request.getParameter("content");
// 원래대로라면 이제 service 호출하고 dao 호출해서 게시글 데이터 insert 쿼리를 진행한다.
// 그리고 그 결과를 돌려받고 성공적으로 추가되었다는 가정 하에
// 응답페이지 : 다시 게시글 전체 조회 페이지로 이동(단, 새로 추가된 데이터도 조회돼서 보여야 한다.)
/*
해결방법.
insert 후에 다시 select하고 게시글전체조회페이지로 이동해야됨
근데 jdbc 과정으로 DB로부터 데이터를 조회해서 해당 페이지로 이동하는 Servlet이 이미 존재함
(이미 구현했던 BoardList라는 서블릿이 존재함)
=> 해당 Servlet을 재 호출하면 됨.
*/
response.sendRedirect("/servlet/list.bo"); // => list.bo의 Servlet을 재실행 (재요청)
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- 곧바로 페이지 이동이 아니라, jdbc 과정으로 db로부터 데이터를 조회한 후에 페이지 이동했다. (서블릿으로)
forward가 아닌 redirect를 했다.
- /list.bo라는 url mapping 값을 가지는 boardList라는 서블릿이 구동된다.
jdbc 과정을 통해서 조회가 진행되고, 포워딩 방식으로 boardList.html 페이지로 이동도 진행된다.
- 수시로 이클립스, vscode 저장하고 서버 재시작, 프로젝트-클린, 브라우저 새로고침 한다.
- 등록하기를 누르면
- list.bo로 노출된다.
- 어떨때 포워딩하고 redirect하는지가 문제다.
요청 처리 후에 어떤 과정을 진행시키고 싶은지를 생각해보라.
근데 이미 그 과정을 해주는 서블릿이 있다면 그 서블릿을 redirect로 재호출하면 된다.
ㅁ < redirect >
- 기존에 정의해둔 Servlet을 재실행 시키는 개념 (URL 요청과 동일)
- 등록 및 수정/삭제 후에 다시 조회 페이지를 요청할 때 주로 사용함
- redirect 시 현재 서블릿에 존재하는 request, response를 전달하지 않음.
서블릿이 새로 실행되는 것이기 때문에 저 객체들도 다시 생성된다.
- 요청할 URL 작성시 contextPath부터 작성
(action에 작성했던 것처럼 절대경로 방식으로)
response.sendRedirect("/servlet/list.bo"); <- 이 경로가 보여지게 된다.
- 클라이언트 측에서 redirect된 경로(최종 목적지)를 확인할 수 있음
URL에 현재 redirect한 URL이 보여진다.
- 주로 redirect 하는 경우
1) insert 쿼리 이후 => 게시글의 전체 조회 페이지 redirect
2) update 쿼리 이후 => 게시글의 상세 조회 페이지 redirect
3) delete 쿼리 이후 => 게시글의 전체 조회 페이지 redirect
'05_Server (04. JSP 프로그래밍 구현)' 카테고리의 다른 글
화면구현 - 웹사이트 개발 화면 구현 (BootStrap) (3) | 2024.08.28 |
---|---|
[Servlet + JSP] 서블릿과 JSP 결합 (5) | 2024.08.28 |
[JSP] JSP (0) | 2024.08.27 |
[Servlet] 서블릿(1) - 프로젝트 세팅(만들기) (2) | 2024.08.26 |
[Servlet] 초기세팅 (워크스페이스, 서버) (1) | 2024.08.26 |