ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SpringMVC (2) - 서블릿
    Web/Spring 2023. 10. 2. 11:19

    - 서블릿 생성방법, HttpServletRequest와 Response에 대해서 알아보자 

    - reqeust는 HTTP 요청 메시지 파싱한 결과 담김 -> 편리하게 조회 

    - response는 HTTP 응답 메시지 쉽게 만들도록 함 -> set이 편리 

     

    *request는 요청 보내는 거 아님, 받은 요청을 읽는 것 따라서 content-type이나,인코딩 등등은 클라이언트가 요청 메시지 보내면서 잘 만들어서 보내야함 

     

    *서블릿은 톰캣 같은 서블릿을 지원하는 애플리케이션 서버를 직접 설치 -> 그 위에 서블릿 클래스 파일을 빌드해서 오린다음 -> 톰캣 서버를 실행함 (스프링 부트는 내장 톰캣 서버를 사용함)

    * ex war파일로 프로젝트를 export하고, 외장 톰캣 서버 webapp폴더에 이를 집어넣고,cmd를 통해 서버를 구동시켜야함 

    (이때, 수정할때마다 다시 war파일로 export한 뒤, 과정 반복 번거로움 -> 이클립스는 WTP를 통해 외부에서 설치한 톰캣서버에 대한 임시 배치 폴더를 내부에 만들어서 (이클립스 복사본) 이 과정을 쉽게 해결함) 

     

    1. Hello 서블릿 

     

    - 스프링 부트 환경에서 서블릿을 등록하고 사용

     

    1.1 스프링 부트 서블릿 환경 구성 

     

    @ServletComponentScan : 스프링 부트에서 서블릿을 직접 등록해서 사용할 수 있도록 위 어노테이션 지원함

                                                 서블릿을 자동 등록 

    @WebServlet : 서블릿 어노테이션 

                             속성은 name와 urlPatterns

                              HTTP 요청을 통해 매핑된 URL이 호출되면, 서블릿 컨테이너는 service 메서드를 실행함 

     

    *서블릿은 톰캣과 같은 WAS(서블릿 컨테이너)를 통해 생명주기가 관리됨 (싱글톤) 

    *서블릿을 직접 실행하는게 아니라, WAS를 실행하면, 프로젝트 내에 등록된 서블릿이 WAS를 통해 생성되고 관리됨

     

    1.2 HTTP 요청 메시지 로그 확인하기 

     

    -application.properties에 다음 설정을 추가하자

    logging.level.org.apache.coyote.http11=debug

    - 이를 추가하고, 요청을 해보면, 서버가 요청받은 HTTP 메시지 출력함

     

    1.3 서블릿 컨테이너 동작 방식 

     

    출처: 스프링 MVC (인프런) - 김영한

    - 내장 톰캣 서버가 서블릿 생성 -> 요청 들어오면 WAS가 먼저 받아서 HTTP메시지 기반 request,response생성

     

    * request,response는 HttpServletRequest,HttpServletResponse의 구현체임 WAS가 구현 객체 만들어서 넣어줌

     

    1.3 웰컴페이지 추가

     

    - webapp경로에 index.html을 두면, 기본 호출시 이 페이지가 열림 

     

     

    2. HttpServletRequest - 상세정보

     

    - HTTP 요청 메시지를 파싱해주는 역할을 해준다. (WAS가 파싱해서 위 객체에 담아서 제공함)

    - HTTP 요청 메시지를 편리하게 조회 가능 

     

    POST /save HTTP/1.1
    Host: localhost:8080
    Content-Type: application/x-www-form-urlencoded
    username=kim&age=20

    START LINE(메서드,URL,쿼리,스키마 - 프로토콜), 헤더, 바디 형식

    위 내용을 파싱해줌

    + 임시 저장소 기능 ( 요청이 시작하고 끝날 때 까지 유지되는 임시 저장소 기능)

    + 세션 관리 기능 (request.getSession)

     

    * HttpServeltRequest와 Response는 HTTP 요청+응답 메시지 편리하게 사용하도록 돕는 객체 따라서 기능에 대한 깊은 이해를 위해서는 HTTP 스펙이 제공하는 요청 응답 메시지를 이해해야함

     

    2.1 HttpServletRequest 기본 사용법 

     

    // startLine
    request.getMethod() 
    request.getProtocol()
    request.getSchme()
    request.getRequestURL() // http://부터 출력
    request.getRequestURI() // /path 만 출력
    request.getQueryString()
    request.isSecure() // https사용여부 검사 
    
    //start-line에 모든 항목 출력가능
    //Header정보
    
    request.getHeaderNames().asIterator().forEachRemaining(headerName ->
    request.getHeader(headerName))

    -> 헤더는 key:value 형식임 Header이름을 얻어서 모든 헤더 값을 출력 

    //Header 몇가지 편리하게 조회
    
    request.getServerName() //Host 헤더의 값 조회
    request.getServerPort() //Host 헤더의 값
    
    //(Accept - Language 조회)
    request.getLocales().asIterarot.forEachRemaining(locale -> ..);
    request.getLocale()
    
    //쿠키 조회 
    request.getCookies() //-> cookie배열 return -> iter가능
    
    //Content 편의 조회 
    request.getContentType()
    request.getContentLength()
    request.getCharacterEncoding()

    *원래는 헤더이름 집어넣고 복잡시럽게 얻어야하는데, 자주 조회되는 헤더는 위와 같이 편리하게 조회하도록 메서드화 함 

     

    *기타 정보를 얻을 수 있는데, 이는 HTTP 메시지 정보는 아님

    (RemoteHost, RemoteAddr,RemotePort,LocalName,LocalAddr,LocalPort 등)

    (IPv4정보를 얻고 싶으면, VM options 뭐 추가해주면됨 (PDF참조)

     

    3. HTTP 요청 데이터 - 개요

     

    - HTTP 요청 메시지는 클라이언트가 서버로 데이터를 전달하는 방법이다.

    - 주로 3가지를 사용한다.

     

    -  쿼리 파라미터 사용(GET) : 메시지 바디 x URL에 데이터 포함해서 전달 (검색,필터,페이징) 

     

    -  HTML FORM (POST) :  메시지 바디에 쿼리 파라미터를 전달 

                                             (요청헤더) content-type:application/x-www-form-urlencoded 

                                             (회원가입,상품주문 등)

     

    - HTTP message body (HTTP API에서 주로 사용 JSON,XML)

     

    *HTTP message body를 사용하는 방법은 마치 웹브라우저 도움 없이 요청을 날리는 느낌 

    HTTP 스펙을 맞추기 위해 요청url,메서드 등등 하나씩 지정해서 요청 날리면 결과 받음 

    받은 결과는 json형식으로 데이터 넘어옴 -> 파싱해서 사용하면 됨 

     

    3.1 쿼리 파라미터 GET

     

    - 쿼리 파라미터 형식으로 데이터가 넘어오면, request.getParameter를 사용해서 간단하게 조회 가능 

    Enumeration<String> prameterNames = request.getParameterNames() // 이름 모두 조회
    Map<String,String[]> paramterMap = request.getParamterMap() // Map으로 모두 조회
    String[] values = request.getParameterValues("name") // 같은 key로 여러 값이 넘어 올때
    String value = request.getParameter("name") // key - value 형태일 때

     

    * 파라미터 이름은 하나 일때 값이 여러개 넘어올 때 getParameter()를 사용하면, getParameterValues중 첫번째 값만 넘어옴

     

    3.2 HTML Form (POST)

     

    - 폼을 통해 넘어온 데이터를 조회하는 방법을 알아보자 

    - content-type : application/x-www-form-urlencoded

    - message body : 쿼리스트링 처럼 넘어옴 

    - 폼을 통해 넘어온 데이터는 쿼리스트링처럼 동일하게 사용가능함 

     

    * 쿼리 스트링 방식은 content-type 헤더가 없음 (바디 사용 안해서)

       폼 형식바디를 사용하므로, 요청시 content-type을 꼭 지정해야함 (메시지에 지정해서 보내야함)

     

    3.3 HTTP 요청 데이터 (HTTP API)

     

    - 단순히 text를 바디에 담아서 전송하고, 읽어보자 

    - HTTP 메시지 바디의 데이터를 InputStream을 사용해서 읽을 수 있음! 

    ServletInputStream is = request.getInputStream();
    String messageBody = StreamUtils.copyToString(is,StandardCharsets.UTF-8);

    *InputStream은 byte코드 반환 -> 문자로 바꾸려면 문자표(Charset)을 지정해 줘야함 

    *InputStream을 열고, StreamUtils를 통해 안에 내용을 String으로 복사 

     원래라면 read()같은 메서드가 -1 반환안할 때 까지 읽어줘야..

     

    3.4 HTTP 요청 데이터 - JSON

     

    - json 타입을 메시지 바디에 사용하는 경우 content-type은 application/json

    - String으로 읽는 부분까지는 동일 ObjectMapper추가 

     

    *ObjectMapper는 Json to 객체 해줌

     

    ServletInputStream is = request.getInputStream();
    String messageBody = StreamUtils.copyToString(is,StanderdCharsets.UTF_8);
    
    HelloData hd = ObjectMapper.readValue(messageBody,HelloData.class);

    * JSON 파싱해서 객체 변환하려면, 변환 라이브러리가 필요한디 스프링 부트는 Spring MVC를 선택시 Jackson라이브러리 제공함

     

     

    4. HttpServletResponse - 사용법

     

    - 응답메시지는: 응답코드,헤더,바디를 생성해서 응답해야함 (이런 기능 제공)

    - 편의기능 : Content-Type, 쿠키 , Redirect

     

    response.setStatus() // 요청 상태
    request.setHeader("헤더명","value");
    
    //message body
    respnse.getWriter() //String으로 응답
    //contentType
    
    response.setContentType("text/plain");
    response.setCharacterEncoding("utf-8");
    
    //Cookie
    
    //원래는 응답헤더에 포함해야해서 복잡 귀찮음 
    Cookie cookie = new Cookie("myCookie", "good");
    cookie.setMaxAge();
    response.addCookie();
    
    /redirect
    
    response.sendRedirect("path");
    //원래는 setStatus,SetHeader("Location","path") 해야함 귀찮

     

    4.1 HTTP 응답 데이터 - 텍스트 or HTML

     

    - HTML응답은 contextType을 text/html, 인코딩을 utf-8로 한다음 getWriter를 얻어서 html문서 만들어서 보내면 됨

    - Json은 content Type을 application/json으로 설정 인코딩 utf-8

    - json으로 만들어서 넘길 객체를 ObjectMapper를 사용해서 넘김 

     

    HelloData data = new HelloData();
    dara.setUsername();
    data.setAge();
    
    
    String result = objectMapper.writerValueAsString(data);
    response.getWriter().writer(result);

    * content-type이 application/json이면, utf-8형식 사용하도록 정의됨 따라서 

    chatset=utf-8 등 추가 파라미터 지원 안함 

    content-type쓸때 application/json;charset=utf-8 하면 의미없는 파라미터 추가된 것 

    response.getWriter()를 사용하면, 추가 파라미터를 자동으로 추가하고, getOutputStream()사용하면 그런 문제 없다.

     

     

     

    참고자료: 

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

     

    스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

    웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

    www.inflearn.com

     

Designed by Tistory.