minghxx.blog
  • [Spring] 스프링 MVC 1편 2) 서블릿
    2023년 11월 01일 17시 27분 45초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    스프링 MVC 1편 백엔드 웹 개발 핵심 기술

    Session 2 서블릿

    1. 프로젝트 생성

    1) 프로젝트 생성

    스프링 부트 스타터 사이트에서 생성

    https://start.spring.io/

    Packaing - War 선택 ▶ JSP 사용하기 위함

    이전 포스팅 참고해서 세팅 ▶ Spring 프로젝트 생성


    2. hello 서블릿

    서블릿은 톰캣같은 웹 애플리케이션 서버를 직접 설치하고 그 위에 서블릿 코드를 클래스 파일로 빌드해서 올린 다음, 톰캣 서버를 실행하면 된다 ▶ 스프링 부트는 톰캣 서버를 내장하고 있으므로, 톰캣 서버 설치 없이 편리하게 서블릭 코드 실행

     

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

    @ServletComponentScan

    서블릿을 직접 등록해 사용할 수 있는 애노테이션

    스프링이 자동으로 패키지에 있는 서블릿을 찾아 자동으로 등록

     

    2) 서블릿 등록하기

    @WebServlet ▶ 서블릿으로 등록하기위한 애노테이션

    @WebServlet(name="helloServlet" urlPatterns="/hello")
    // name : 서블릿 이름
    // urlPatterns : URL 매핑
    // 중복되면 안된다!

    service 메서드 오버라이딩 ▶ 매핑된 url이 호출되면 서블릿 컨테이너가 서비스 메서드 실행

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	// 쿼리파라미터 조회
    	String username = request.getParameter("username");
        
    	// response content 타입, 인코딩 지정
    	response.setContentType("text/plain");
    	response.setCharacterEncoding("utf-8");
        
    	// response 응답 메세지 전송
    	response.getWriter().write("hello " + username);
        
    	// HTTP 응답, 요청을 편리하게 서블릿이 도와줌
    }

     

    3) 서블릿 컨테이너 동작 방식 설명

    스프링 부트를 실행하면 내장 톰캣 서버를 띄워줌

    내장 톰캣 서버는 내부의 서블릿 컨테이너 기능을 가지고 서블릿을 생성(helloServlet 생성)

     

    URL를 입력하면 웹브라우저가 HTTP 요청메시지를 작성 서버로 전송

     

    웹 애플리케이션 서버 요청 응답 구조

    서버가 request, response 객체를 만들어 helloServlet에 서비스 메서드를 호출하면서 request, response 객체 넘겨줌

    서비스 메서드 실행 결과를 서버에 주면 response 객체에 HTTP 응답 메시지를 생성해 클라이언트에게 전달


    3. HttpServletRequest 개요

    1) HttpServletRequest 역할

    서블릿은 HTTP 요청 메시지를 편리하게 사용할 수 있도록 대신 파싱해 제공

    HTTP 요청 메세지 파싱 결과를 HttpServletRequest 객체에 담아서 제공, HTTP 요청 메시지 편리하게 조회가능

     

    2) HTTP 요청 메시지

    HttpServletRequest 사용해 편리하게 조회

    HTTP 요청메세지
    POST /save HTTP/1.1 // Start line
    Host: localhost:8080 // header
    Content-Type: application/x-www-form-urlencoded
    
    //body
    username=kim&age=20

    START LINE ▶ HTTP 메서드, URL, 쿼리 스트링, 스키마, 프로토콜

    헤더 ▶ 헤더 조회

    바디 ▶ form 파라미터 형식, 메세지바디 데이터 직접 조회

     

    3) HttpServletRequest 객체의 부가기능

    -임시 저장소 기능

    해당 HTTP 요청이 시작부터 끝날 때까지 유지되는 임시 저장소

    저장 request.setAttribute(name, value);

    조회 request.getAttribute(name);

    -세션 관리 기능

    request.getSession(create: true);

    -중요

    HttpServletRequest, HttpServletResponse를 사용할 때 가장 중요한 점은 이 객체들이 HTTP 요청, 응답 메시지를 편리하게 사용하게 도와주는 객체라는 점

    깊이 있는 이해를 하려면 HTTP 스펙이 제공하는 요청, 응답 메시지 자체를 이해해야 한다!


    4. Http 요청 데이터 - 개요

    1) HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법

    -GET+쿼리 파라미터

    메시지 바디 없이 URL의 쿼리 파라미터에 데이터 포함해서 전달

    검색, 필터, 페이징 등에 많이 사용

    -POST+HTML Form

    메시지 바디에 쿼리 파라미터 형식으로 전달 → content-type: application/x-www-form-urlencoded의미

    회원가입, 상품주문, HTML Form 사용

    -HTTP 메시지 바디

    HTTP API에서 주로 사용 JSON, SML, TEXT

    데이터 형식은 주로 JSON 사용

    POST, PUT, PATCH

     

    2) POST-HTMLForm 예시


    5. HTTP 요청 데이터 - GET 쿼리 파라미터 

    1) 메시지 바디 없이 쿼리 파라미터 사용

    쿼리 파라미터를 URL에 ? 시작으로 키=값 형태로 전달, 추가 파라미터는 & 구분

    서버에서는 HttpServletRequest가 제공하는 메서드 통해 쿼리 파라미터 편리하게 조회가능

     

    2) 쿼리 파라미터 조회 메서드

    String username=request.getParameter("username");//단일 파라미터 조회 
    Enumeration<String>parameterNames=request.getParameterNames();//파라미터 이름들 모두 조회
    Map<String, String[]> parameterMap = request.getParameterMap(); //파라미터를 Map 으로 조회
    String[]usernames=request.getParameterValues("username");//복수 파라미터 조회

     

    3) 복수 파라미터에서 단일 파라미터 조회

    getParameter()는 하나의 파라미터 이름에 대해서 단 하나의 값만 있을 때 사용

    파라미터 이름은 하나인데 값이 중복이면 getParameterValues()메서드 사용

    중복일 때 getParameter()를 사용하면 getParameterValues()의 첫 번째 값을 반환


    6. HTTP 요청 데이터 - POST HTML Form

    1) 특징

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

     메시지 바디에 쿼리 파라미터 형식 키=값으로 전달

     

    2) form 데이터 전송

    요청 URL : http://localhost:8080/request-param

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

    message body : username=hello&age=20

     

    3) application/x-www-form-urlencoded 형식

    GET에서 사용했던 쿼리 파라미터 형식과 같다.

    쿼리 파라미터 조회 메서드를 그대로 사용

    클라이언트(웹브라우저) 입장에서는 두 방식의 차이가 있지만 서버에서는 형식이 동일하므로 getParameter() 메서드로 구분 없이 사용

     

    4) postman으로 테스트하기


    7. HTTP 요청 데이터 - API 메시지 바디 +단순텍스트

    1) HTTP 메시지 바디에 데이터를 직접 담아서 요청

    HTTP API에서 주로 사용

    데이터 형식은 JSON, XML, TEXT 중 JSON 주로 사용

    POST, PUT, PATCH

     

    2) InputStream

    텍스트 메시지를 메시지 바디에 담아서 전송, InputStream을 사용해 직접 읽을 수 있다.

    InputStream은 byte 코드를 반환, String으로 보려면 charset을 지정 필요

    ServletInputStream inputStream = request.getInputStream();
    // 스프링이 스트림을 편리하게 사용할 수 있게 StreamUtils 제공
    String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    
    System.out.println("messageBody = " + messageBody);
    response.getWriter().write("ok");

    8. HTTP 요청 데이터 - API 메시지 바디 +JSON

    1) JSON 형식으로 데이터 전달

    JSON을 주로 객체로 바꿔서 사용

     

    2) json 형식 파싱

    json 형식으로 파싱 할 수 있게 객체 생성

    public class HelloData {
        private String username;
        private int age;
    }
    // json 데이터를 객체로 사용하기 위한 라이브러리가 필요
    private ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    
        System.out.println("messageBody = " + messageBody);
    
        // 객체로 변환
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
        System.out.println("helloData.username = " + helloData.getUsername());
        System.out.println("helloData.age = " + helloData.getAge());
    }

     

    3) Jackson 라이브러리

    json 결과를 파싱해 객체로 사용하기 위해선 라이브러리를 추가해 사용

    스프링 부트로 SpringMVC를 선택하면 기본으로 Jackson 라이브러리(ObjectMapper)를 함께 제공


    9. HttpServletResponse 기본 사용법 

    1) HttpServletResponse 역할

    -HTTP 응답 메시지 생성

    HTTP 응답코드 지정, 헤더, 바디 생성

    -편의기능 제공

    Content-Type, 쿠키, Redirect

    // 상태코드 설정
    response.setStatus(HttpServletResponse.SC_OK);
    
    // 메시지 바디
    PrintWriter writer = response.getWriter();
    writer.println("ok");
    
    // 편의 기능
    response.setContentType("text/plain"); 
    response.setCharacterEncoding("utf-8");
    response.setContentLength(2); //(생략시 자동 생성)
    
    // 쿠키
    Cookie cookie = new Cookie("myCookie", "good"); 
    cookie.setMaxAge(600); //600초
    response.addCookie(cookie);
    
    // 리다이렉트
    response.sendRedirect("/basic/hello-form.html");

    10. HTML 응답 데이터 - HTML

    1) HTML 응답 데이터

    단순 텍스트 응답 : wirte.println("ok");

    HTML응답

    HTTP API 메시지바디 JSON응답

     

    2) HttpServletResponse - HTML 응답

    //Content-Type: text/html;charset=utf-8
    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>");

    Content-Type을 text/html로 지정

    서블릿으로 html을 렌더링 하려면 직접 HTML을 작성


    11. HTML 응답 데이터 - API JSON

    1) HTML 응답 데이터 API JSON

    private ObjectMapper objectMapper = new ObjectMapper(); //json 사용하기위해 라이브러리 사용
    
    //Content-Type: application/json
    response.setHeader("content-type", "application/json");
    response.setCharacterEncoding("utf-8");
              
    HelloData data = new HelloData();
    data.setUsername("kim");
    data.setAge(20);
    
    //{"username":"kim","age":20}
    String result = objectMapper.writeValueAsString(data);
    response.getWriter().write(result);

    Content-Type을 application/json으로 지정

    Jackson 라이브러리가 제공하는 objectMapper.writeValueAsString() 사용하면 객체를 json 문자로 변경 가능

    application/json 스펙상 utf-8 형식을 사용하도록 정의 ▶ application/json;charset=utf-8 의미 없는 파라미터 추가한 것임

    ▶ response.getWriter()를 사용하면 자동으로 추가함

    ▶ response.getOutputStream()으로 출력하면 문제 해결!

     

    728x90
    댓글