서블릿

Joo·2022년 11월 16일
0

스프링 MVC 1편

목록 보기
2/7

2.1 서블릿 실행 환경 설정

  • 스프링 부트 환경에서 서블릿 등록
    • 원래는 톰캣같은 WAS를 직접 설치하고 그 위에 서블릿 코드를 클래스로 빌드해서 올린 다음 톰캣을 실행해야 함
    • 스프링 부트는 톰캣 서버를 내장하고 있기 때문에 별도로 톰캣을 설치하지 않아도 됨
    • Packaging : War (Jar 아님) → JSP를 실행하려면 War로 해야함

서블릿 어노테이션

@ServletComponentScan

@ServletComponentScan
@SpringBootApplication
public class ServletApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServletApplication.class, args);
	}

}
  • 스프링 부트가 서블릿을 직접 등록해서 사용할 수 있도록 지원함
    • @WebServlet 붙어있는 클래스를 서블릿으로 등록

@WebServlet

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("request = " + request);
        System.out.println("response = " + response);

        String username = request.getParameter("username");
        System.out.println("username = " + username);

        // http 헤더 정보
        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");

        // http 메시디 바디 정보
        response.getWriter().write("hi");
    }
}
  • name
    • 서블릿 이름
  • urlPatterns
    • URL 매핑
    • 해당 url이 호출되면 서블릿 컨테이너가 service 메소드를 실행함

HTTP 요청 메시지 로그 확인

  • application.properties
    logging.level.org.apache.coyote.http11=debug
    • 모든 요청 정보를 남김 → 성능 저하를 유발할 수 있으므로 개발 단계에서만 적용

웹 애플리케이션 동작 방식

  1. 클라이언트의 HTTP 요청

  2. WAS가 request, response 객체를 생성하여 요청 URL에 해당하는 서블릿에 전달, 서블릿 호출

  3. service 메소드를 실행하고 response 객체에 처리한 데이터를 담음

  4. WAS가 response 객체 정보를 기반으로 HTTP 응답 메시지 생성

  5. 클라이언트에게 HTTP 응답

2.2 HttpServletRequest

1. 역할

HTTP 요청 메시지를 파싱해서 HttpServletRequest 객체에 담아서 제공

  • HTTP 요청 메시지

    1. start line
      • HTTP 메소드
      • URL
      • 쿼리 스트링
      • 스키마, 프로토콜
    2. header
      • 헤더 조회
    3. message body
      • form 파라미터 형식 조회 → getParameter()
      • 데이터 직접 조회 → JSON 형식 데이터

2. 기능

  • 임시 저장소 기능
    • HTTP 요청의 시작부터 끝까지 유지됨
      • 저장 : request.setAttribute(name, value)
      • 조회 : request.getAttribute(name)
  • 세션 관리 기능
    • request.getSession(create:true)

3. 메소드

  • start line 정보
    GET /search?q=hello&hi=ko HTTP/1.1
    1. getMethod()
      • HTTP 메소드를 조회
      • GET, POST..
    2. getProtocol()
      • HTTP 버전 조회
      • HTTP/1.1
    3. getSchema()
      • http, https, ftp와 같은 프로토콜
    4. getRequestURL()
    5. getRequestURI()
      • URL에서 스키마, 서버이름, 포트번호를 제외한 나머지 주소 리턴
      • /request-header
    6. getQueryString()
    7. isSecure()
      • https와 같은 보안 채널의 사용 여부
  • header 정보
    Host: www.google.com
    • getHeader(headerName)
    • header 관련 정보를 편리하게 조회
      1. getServerName()
        • 서버 이름
        • localhost
      2. getServerPort()
        • 서버 포트
        • 8080
      3. getLocale()
        • 지역 정보
        • getLocal : ko_KR
      4. getCookies()
        • 모든 쿠키값
      5. getContentType()
      6. getContentLength()
      7. getContentEncoding()
  • 기타 정보 (HTTP 메시지 정보 x)
    • 클라이언트 정보
      1. getRemoteHost()
      2. getRemoteAddr()
      3. getRemotePort()
    • 서버 정보
      1. getLocalName()
      2. getLocalAddr()
      3. getLocalPort()

4. 요청 데이터 조회

  • content-type
    • HTTP 메시지 바디의 데이터 형식을 지정
    • GET 쿼리 파라미터 형식은 메시지 바디를 사용하지 않음 ⇒ content-type 없음
  • 클라이언트 → 서버 데이터 전송 방법 3가지

    절대 이 3가지 방법을 벗어나지 않는다!

    1. GET 쿼리 파라미터
      • 메시지 바디 없이 쿼리 파라미터에 데이터를 포함해서 전달
        • 검색, 필터 등에서 많이 사용하는 방식
      • ?로 시작하고 파라미터는 &로 구분
      • 쿼리 파라미터 조회 메소드
        1. getParameter() → 가장 많이 사용
          • 단일 파라미터 조회
        2. getParameterNames()
          • 파라미터 이름들 모두 조회
        3. getParameterMap()
          • 파라미터를 Map으로 조회
        4. getParameterValues()
          • 복수 파라미터 조회
          • 복수 파라미터에서 단일 파라미터 조회를 하는 경우
            • getParameterValues()의 첫 번째 값을 반환 ex) username=kim&username=joo → kim 반환
    2. POST HTML Form
      • content-type : application/x-www-form-urlencoded
      • 메시지 바디에 쿼리 파라미터 형식으로 전달
        • 쿼리 파라미터 조회 메소드를 사용할 수 있음
      • 웹 브라우저에서 HTTP 요청 메시지 생성해서 서버로 전달
    3. API 메시지 바디
      • 메시지 바디에 데이터를 직접 담아서 요청
      • HTTP API에서 주로 사용하는 방식
      • POST, PUT, PATCH
      • InputStream을 사용해 읽음
      1. 단순 텍스트
        • 텍스트를 메시지 바디에 넣어서 보내는 경우
        • content-type : text/plain
          ServletInputStream inputStream = request.getInputStream();
          String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
      2. JSON
        • JSON 형식의 데이터를 메시지 바디에 넣어서 보내는 경우
        • content-type : application/json
        • JSON 형식의 데이터를 파싱해서 자바 객체로 변환
          • Spring MVC는 기본으로 JSON 변환 라이브러리Jackson 라이브러리(ObjectMapper)를 제공

            private ObjectMapper objectMapper = new ObjectMapper();
            
            ServletInputStream inputStream = request.getInputStream();
            String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
            
            HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
            
            System.out.println("helloData.userName : " + helloData.getUserName());
            System.out.println("helloData.age : " + helloData.getAge());
          • objectMapper.readValue(String, 타입);

            • String(JSON) → 객체 변환하는 메소드

2.3 HttpServletResponse

1. 역할

HTTP 응답 메시지를 만드는데 사용

  • HTTP 응답 메시지

    1. HTTP 응답 코드 지정
    2. 헤더 생성
    3. 바디 생성

2. 기능

  • content-type
  • 쿠키
  • redirect

3. 메소드

start line 지정

HTTP/1.1 200 OK
  • setStatus(HttpServletResponse.상수) → 다양한 상수 존재
response.setStatus(HttpServletResponse.SC_OK);

헤더 생성

Content-Type: text/html;charset=UTF-8
Content-Length: 3423
  • setHeader(헤더이름, 헤더내용)
response.setHeader(”Content-Type”, “text/plain;charset=utf-8”);

바디 생성

  • getWriter().write(”바디에 들어갈 내용”);
    PrintWriter writer = response.getWriter();
    writer.write("ok");

편의 기능

  • content
    // = response.setHeader("Content-Type", "text/plain;charset=utf-8");
    response.setContentType("text/plain");
    response.setCharacterEncoding("utf-8");
  • cookie
    // = response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
    Cookie cookie = new Cookie("myCookie", "good");
    cookie.setMaxAge(600); //600초
    response.addCookie(cookie);
  • redirect
    //response.setStatus(HttpServletResponse.SC_FOUND); //302
    // = response.setHeader("Location", "/basic/hello-form.html");
    response.sendRedirect("/basic/hello-form.html");

4.응답 데이터 보내기

단순 텍스트

  • getWriter().write(”텍스트”);
    response.setContentType("text/plain");
    response.setCharacterEncoding("utf-8");
    
    PrintWriter writer = response.getWriter();
    writer.write("ok");

HTML

  • writer로 HTML 한 줄씩 출력 → 굉장히 번거로움 → 그래서 나온게 JSP
    response.setContentType("text/html");
    response.setCharacterEncoding("utf-8");
    
    PrintWriter writer = response.getWriter();
    
    writer.println("<html>");
    writer.println("<body>");
    writer.println(" <div>안녕?</div>");
    writer.println("</body>");
    writer.println("</html>");

API JSON

  • getWriter().write(인스턴스);
    response.setContentType("application/json");
    response.setCharacterEncoding("utf-8");
    
    HelloData helloData = new HelloData();
    helloData.setUserName("Kim");
    helloData.setAge(20);
    
    String result = objectMapper.writeValueAsString(helloData);
    
    response.getWriter().write(result);
  • objectMapper.writeValueAsString(…);
    • 객체 → String(JSON) 변환하는 메소드

💡 InputStream ——StreamUtils.copyToString()——> String(JSON) ——objectMapper.readValue()——> Object

💡 Object——objectMapper.writeValueAsString()——>String(JSON)

0개의 댓글