。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-81일차(8월22일)] - 웹프로그래밍 62일차

quarrrter 2023. 8. 22. 14:45

오늘의 목표: initial parameter 

 

init parameter : 필터나 서블릿을 생성할 때 전달하는 값 

전달하는 방법: Annotation or DD file(web.xml) 배치설명파일 

-----

유사 사례 1. App을 시작할 때 전달하는 값 : 프로그램 아규먼트, JVM 아규먼트

꺼내는 법: main(args~) / sys.get~


load on startup 

load on startup - 서블릿 객체 자동 생성하기(애노테이션으로 설정하기)

클라이언트가 실행을 요청하지 않아도 서블릿을 미리 생성하고 싶다면,
loadOnStartup 프로퍼티 값을 지정하라.
    loadOnStartup=실행순서
미리 생성할 서블릿이 여러 개 있다면, loadOnStartup에 지정한 순서대로 생성한다.

	서블릿을 미리 생성 경우
=> 서블릿이 작업할 때 사용할 자원을 준비하는데 시간이 오래 걸리는 경우
   웹 애플리케이션을 시작할 때 미리 서블릿 객체를 준비하는 것이 좋다.
   예) DB 연결, 소켓 연결, 필요한 환경 변수 로딩, 스프링 IoC 컨테이너 준비 등

1. dd파일로 생성

http:localhost:8888/ex06.s1 하면 그 때 호출됨

url 치면 해당되는 서블릿 객체를 찾고 생성 안 되어있으면 init로 생성하고 이미 있으면 있는거 쓰고 , 이미 있으면 service호출함

요청하지 않아도 서버 시작하면 자동으로 시작됨

2. 애노테이션으로 설정


서블릿 초기화 파라미터

서블릿 초기화 파라미터 - web.xml에서 설정하기

web.xml
서버 실행 후 확인 가능 init() 에 설정해서. service()에도 적용가능함.

 

서블릿 초기화 파라미터 - 애노테이션으로 설정하기

web.xml에 데이터가 있으면 그냥 파일만 바꾸면 됨. 소스 재컴파일 할 필요없음.

근데 애노테이션 쓰면 다시 컴파일해야해서 애노테이션으로 설정하는 방법은 비추임 ㅡ.,ㅡ ! 

 


필터 초기화 파라미터

필터 초기화 파라미터 : web.xml에서 설정한 값 가져오기

web.xml   필터는 웹앱 시작될때 자동생성됨
웹 앱 실행하니까 do filter 실행되면서 설정한거 호출됨

필터 초기화 파라미터 : 애노테이션으로 설정한 값 가져오기

웹앱 실행하면 콘솔창에 짠


context parameter: : 서블릿과 필터가 공유하는 파라미터 

한 서블릿에서 지정한 파라미터는 그 서블릿만 사용가능하다. 

공통으로 사용할 수 있는 것이 context parameter

직접 꺼낼 수 없다 .

// 컨텍스트 초기화 파라미터 - web.xml에서 설정하기


forwarding / including

1. forwarding

포워딩(s1->s2) 하는 순간 s1이 다 없어짐 . 

 

더보기

더하기

서버에 '+' 문자를 전송하면 url 디코딩 할때  '+'문자가 아닌 공백(' ')문자가 전달되기 때문
 주의!
 => + 연산을 수행하지 못한다.
서버에 '+' 문자를 전송하면 url 디코딩 할때  '+'문자가 아닌 공백(' ')문자가 전달되기 때문
 왜? 서버에 전송될 때 '+'문자가 아닌 공백(' ')문자가 전달되기 때문이다.
 => + 연산자를 파라미터 값으로 보내고 싶다면 URL 인코딩 해야 한다.
 => 왜? + 문자는 URL에서 한 칸의 공백을 의미한다.
    즉 getParamter("op")의 리턴 값이 공백(" ") 이다.
 => + 문자의 URL 인코딩 값은?
 %2b
 => 따라서 + 연산을 파라미터 값으로 보내려면

 

// 포워딩(forwarding) - 서블릿 실행을 위임하기

더보기
String op = request.getParameter("op");
if (!op.equals("+")) {
  // 자신의 일이 아니라면 다른 서블릿으로 위임할 수 있다.
  // => 요청을 다른 서블릿으로 전달할 수 있다.
  // 요청배달자 = request.getRequestDispatcher(다른 서블릿 URL);
  RequestDispatcher 요청배달자 = request.getRequestDispatcher("/ex07/s2");

  // 이 서블릿이 지금까지 출력한 것은 모두 취소된다.
  // => 엥! 출력된 것이 최소될 수 있나요?
  // => PrintWriter 객체를 통해 출력하는 내용은 즉시 웹 브라우저로 전달되는 것이 아니다.
  //    내부 출력 버퍼(보통 8KB 크기)에 보관된다.
  // => 서블릿의 service() 메서드 호출이 종료될 때 비로서 버퍼의 내용이
  //    웹 브라우저로 전송된다.
  // => 물론 그 전에 버퍼가 꽉 차면 자동으로 출력된다.
  // => 그래서 다른 서블릿으로 실행을 위임하기 전에
  //    이 서블릿이 출력한 내용을 취소할 수 있는 것이다.
  요청배달자.forward(request, response);

 

곱하기 

곱하기 실행했을 때 리턴 리턴

2. including : 여러 서블릿이 협업하여 요청을 처리

// 인클루딩(including) - 다른 서블릿의 작업을 포함시키기

@WebServlet("/ex07/s11")
@SuppressWarnings("serial")
public class Servlet11 extends HttpServlet {

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();

    out.println("계산 결과:");
    out.println("---------------------------------------");
    String op = request.getParameter("op");

    RequestDispatcher 요청배달자 = null;

    if (op.equals("+")) {
      요청배달자 = request.getRequestDispatcher("/ex07/s11_plus");
    } else if (op.contentEquals("-")) {
      요청배달자 = request.getRequestDispatcher("/ex07/s11_minus");
    } else {
      요청배달자 = request.getRequestDispatcher("/ex07/s11_error");
    }
       // 다른 서블릿을 실행시킨다.
    // => forward()는 다른 서블릿으로 위임할 때 현재 서블릿의 출력을 취소한다.
    // => include()는 다른 서블릿으로 실행을 위임하더라도
    //    현재 서블릿의 실행 결과를 유지한다.
    // => 인클루드의 경우 현재 서블릿에서 setContentType()을 설정해야 한다.
    // => 포워드는 현재 서블릿에서 설정한 setContentType()이 무시된다.
    요청배달자.include(request, response);

    // including 서블릿을 실행한 후에 리턴되면
    // 현재 서블릿은 계속해서 출력할 수 있다.
    // => forwarding 서블릿을 실행한 후에서 리턴되어도
    //    현재 서블릿이 출력할 수 없었다.
    //    정확히 하면 출력한 것이 모두 무시되었다.

    out.println("---------------------------------------");
  }
}


Refresh & Redirect 

refresh : ** 서버가 반드시 컨텐트를 보낸다

redirect: 300번대 : redirection 관련 번호 , 보내는 컨텐트 없음 

// 리프래시
// => 서버로부터 응답을 받고 "내용을 출력"한 후  :: 서버가 반드시 컨턴트를 보낸다
//    지정된 시간이 경과되면 특정 URL을 자동으로 요청하도록 만들 수 있다.
// => 보통 웹 페이지를 자동으로 이동시키고 싶을 때 사용한다.
// => 예
//    예1: 로그인 후 메인페이지로 자동 이동
//    예2: 메일을 전송한 후 메일 목록 페이지로 자동 이동
//    예3: 게시글 등록한 후 게시글 목록으로 자동 이동
//    예4: 결제 완료 후 결제 상태 페이지로 자동 이동
방법 1 : 응답헤더에 refresh 삽입 
response.setHeader("Refresh", "3;url=s100");


방법 2 : HTML을 출력하는 경우
    // 응답 헤더가 아니라 HTML 헤더에 리프래시 명령을 설정할 수 있다.
    out.println("<meta http-equiv='Refresh' content='3;url=s100'>");

    out.println("</head><body>");
    out.println("<h1>안녕하세요! - /ex08/s2</h1>");
    out.println("</body></html>");
  }

 

상대경로 현재 위치의 ,,, 그거 ,,, 

절대경로 : 다 적어줘야함 

// 리다이렉트 - 응답할 때 콘텐트를 보내지 않는다. 바로 다른 페이지를 요청하라고 명령한다.

// 리다이렉트
// => 클라이언트의 요청을 받은 후 콘텐트를 보내는 대신
//    다른 페이지의 URL을 알려줄 때 사용한다.
// => 웹 브라우저는 응답 받는 즉시 해당 페이지를 요청한다.
//    웹 서버로부터 콘텐트를 받지 않았기 때문에 어떤 것도 출력하지 않는다.
//    바로 다른 페이지로 이동한다.
// => 리프래시와 달리 서버는 콘텐트(message-body)를 보내지 않는다.
// => 사용 예:
//    - 로그인 후 로그인 결과를 출력하지 않고 즉시 메인 화면으로 보내고 싶을 때
//    - 결제완료 후 결과를 출력하지 않고 즉시 결제 상태 페이지로 보내고 싶을 때
// => 리다이렉트 HTTP 응답 프로토콜
//
//    HTTP/1.1 302 <----- 리다이렉트 응답 상태 코드
//    Location: s100 <----- 리다이렉트 URL
//    Content-Type: text/html;charset=UTF-8
//    Content-Length: 0
//    Date: Tue, 02 Apr 2019 03:38:45 GMT
//    빈 줄
//         <---- 콘텐트를 보내지 않는다. 즉 message-body가 없다.
//
// 클라이언트에게 URL을 알려줄 때 상대 경로를 지정할 수 있다.
// forward/include 와 달리 '/'는 컨텍스트 루트(웹 애플리케이션 루트)가 아닌
// 웹 서버 루트를 의미한다.
response.sendRedirect("s100");

// 리다이렉트를 하는 순간 이전까지 버퍼로 출력된 내용은 모두 버려진다.
// 왜? 리다이렉트는 클라이언트로 콘텐트를 보내지 않는다.
//
// 만약 출력한 내용이 버퍼를 꽉 채워서 자동으로 응답을 했다면 어떻게 되나요?
// => 이미 응답했기 때문에 리다이렉트는 동작되지 않는다.

실수사례~ 

forward 사용 사례 

forward를 써야 오류도 보는데 redirect하면 출력되는 값이 없이 리스트로 다시 돌아가기때문에 ,, 안 맞음

add일땐 redirect가 적절 

실패메세지 떠야하는건 forward 

forward/ refresh / redirecet 응용

forward 잘못사용예 

포워드를 하면 /board/add 인데 목록이 나옴. board/list에서 출력되어야지 add에 나오면 안됨.

=> 오류가 발생할 땐 error서블릿에 forward 하는 방식으로 하기

 

redirect 응용 

redirect  잘못사용예

(사진 넣기)

 


URL 구분 

 

포워딩, 인클루드할 때 맨 앞에 오는 / 는 컨텍스트 루트다. 서버루트가 아니다.

* forward/ include 서블릿까리 데이터 공유