서블릿

유동우·2023년 4월 3일
0
post-thumbnail

프로젝트 생성


Hello 서블릿

@ServletComponentScan
:스프링이 자동으로 현재 패키지 내 하위 패키지를 모두 뒤져서 서블릿을 찾고, 자동으로 서블릿을 등록 및 실행가능

@WebServlet : 서블릿 애노테이션
name: 서블릿 이름
urlPatterns: URL 매핑

HTTP 요청을 통해 매핑이된 URL이 호출되면 서블릿 컨테이너가 아래 메서드 (서비스메서드) 실행

String username = request.getParameter("username");

getParameter 로 요청받은 쿼리 파라미터 (?username=) 값을 읽을 수 있다.

== 참고 ==

서버가 받은 HTTP 요청 메시지가 콘솔창에 또한 출력된다.

스프링부트 실행 -> 내장톰캣서버(내부에 서블릿 컨테이너 기능을 갖고있다) 띄워줌 -> 서블릿 생성(helloServlet)

HTTP요청이 들어오면 서버는 request, respons 객체를 만든 후 싱글톤으로 떠있는 helloServlet을 호출해준다. -> service 메서드를 호출 -> request, respons를 넘겨준다
-> respons 객체에 원하는 정보를 입력한다 -> WAS 서버가 응답정보를 바탕으로 HTTP 응답 메시지를 만들어서 반환 -> 웹 브라우저에서 HelloWorld 볼 수 있다.


HttpServletRequest - 개요

START LINE

HTTP 메소드
URL
쿼리 스트링
스키마, 프로토콜
ex) POST /save HTTP/1.1

헤더

헤더 조회
ex) Host, Content-Type

바디

form 파라미터 형식 조회
message body 데이터 직접 조회

ex) 헤더 밑 부분 

username=kim&age=20 과 같은 정보가 오면
request.getParameter 로 편리하게 읽을 수 있도록 지원한다

메세지 바디에 JSON 이 많이 들어가도, 메세지를 통으로 읽어들이는 기능도 지원한다.
(JSON을 parsing하려면 라이브러리가 필요함 -> 뒤에서 설명)

HttpServletRequest의 기능
1.임시 저장소 기능

  - 자주 사용된다
  저장: request.setAttribute(name,value)
  조회: request.getAttribute(name)

2.세션 관리 기능

	session? -> 로그인햇다 or 안했다 정보 유지 기능을 제공 

HttpServletRequest - 기본 사용법

start-line 정보

헤더 정보

Enumeration<String> headerNames = request.getHeaderNames();
      while (headerNames.hasMoreElements()) {
          String headerName = headerNames.nextElement();
          System.out.println(headerName + ": " + request.getHeader(headerName));

getHeaderNames(): HTTP 요청 메세지에 있는 모든 헤더 정보를 전부 꺼내서 출력 가능

요즘은 위 코드 말고 아래코드 처럼 간략하게 사용

request.getHeaderNames().asIterator()
        .forEachRemaining(headerName -> 
            System.out.println("headerName = " + headerName));

Header 편리한 조회

기타 정보

a-7a27b7ba3101/image.png)


HTTP 요청 데이터 - 개요

위 세가지 방식 잘 알아둬야 나중에 헷갈리지 않음

GET - 일반 구글 검색시 나오는 엄청 긴 쿼리 파라미터
POST - content-type: 어떤 바디인지 설명 해준다.
HTTP message body에 데이터를 직접 담아서 요청


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

전달 데이터

username=hello
age=20

메시지 바디 없이, URL의 쿼리파라미터(? 과 &)를 사용해서 데이터를 전달하자

  1. 전체 파라미터 조회

  2. 단일 파라미터 조회

  3. 이름이 같은 복수 파라미터 조회 (username=kim&username=you)

(if) value 값이 중복인데 request.getParameterValues(username)을 사용하지 않고
request.getParameter(username)를 사용하면 values 배열의 값들 중 가장 첫 번째 값을 반환한다.


HTTP 요청 데이터 - POST HTML Form

특징
message body가 존재하기 때문에 content-type : 'application/x-www-form-urlencoded' 가 존재한다.
GET 방식과 마찬가지로 message body에 쿼리 파라미터 형식으로 데이터를 전달한다.

request.getParameter()

1. GET 형식 (parameter)
2. POST 형식 (message body, form)

둘 다 모두 조회할 수 있다.
즉, 클라이언트 입장에서는 두 방식이 다르지만
	서버 입장에서는 둘의 형식이 동일하다 
    

정리 => request.getParameter() 는 GET URL 쿼리 파라미터 형식도 지원하고, POST HTML Form 형식도 둘 다 지원한다.


HTTP 요청 데이터 - API 메시지 바디 - 단순 테스트

HTTP message body에 데이터를 직접 담아서 요청
HTTP API에서 주로 사용, JSON, XML ,TEXT
데이터 형식은 주로 JSON 사용

ServletInputStream inputStream = request.getInputStream();
          String messageBody = StreamUtils.copyToString(inputStream,
  StandardCharsets.UTF_8);

HTTP 메시지 바디의 데이터를 InputStream으로 사용해서 "바이트코드"로 직접 읽을 수 있다.
읽은 "바이트코드"의 데이터를 spring에서 지원해주는 StreamUtils를 통해 문자열로 바꿀 수 있다

바이트 코드 <-> 문자열 인코딩 필수


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

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

 @Getter @Setter // lombok 으로 get,set 메서드 생략 가능 
 public class HelloData {
      private String username;
      private int age;
 }

JSON 결과를 파싱해서 자바 객체로 변환하기 위해 JSON 라이브러리 사용
(Spring boot로 Spring MVC를 선택해서 Jackson 라이브러리 함께 제공)

private ObjectMapper objectMapper = new ObjectMapper();

(참고) 전에 했던 두번째 방식인 HTML form 데이터도 결국에는 메시지 바디를 통해 전송되므로 직접 읽을 수 있다.
하지만 request.getParameter() 기능이 있으므로 그냥 파라미터 조회 기능을 사용하면 된다.


HttpServletResponse - 기본 사용법

HTTP 응답 메시지 생성

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

편의 기능 제공

  • Content-Type, 쿠키, Redirect
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //[status-line]
        response.setStatus(HttpServletResponse.SC_OK); //직접 200 적는거보다 이 방식이 낫다.

        //[respons-header]
        response.setHeader("Content-Type", "text/plain;charset=utf-8");
        response.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("my-header", "hello"); //내가 원하는 헤더 만들기

        //[Header 편의 메서드]
//        content(response);
//        cookie(response);
//        redirect(response);


        PrintWriter writer = response.getWriter();
        writer.println("ok");
    }

    private void content(HttpServletResponse response) {
        //Content-Type: text/plain;charset=utf-8
        //Content-Length: 2 // println() 시에는 엔터가 들어가서 글자수 + 1 이 출력
        //response.setHeader("Content-Type", "text/plain;charset=utf-8");
        // response.setContentType("text/plain");
        // response.setCharacterEncoding("utf-8");
        // response.setContentLength(2); // (생략시 자동 생성)
    }

    private void cookie(HttpServletResponse response) {
        //Set-Cookie: myCookie=good; Max-Age=600;
        //response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
        Cookie cookie = new Cookie("myCookie", "good");
        cookie.setMaxAge(600); //600초
        response.addCookie(cookie);
    }

    private void redirect(HttpServletResponse response) throws IOException {
        //Status Code 302
        //Location: /basic/hello-form.html

//        response.setStatus(HttpServletResponse.SC_FOUND); //302
//        response.setHeader("Location", "/basic/hello-form.html");
        response.sendRedirect("/basic/hello-form.html"); //위에 두 줄과 동일
    }

HTTP 응답 데이터 - 단순 텍스트, HTML

** HTTP 응답 메시지는 주로 다음 내용을 담아서 전달한다.

  • 단순 텍스트 응답 ('writer.println("ok"));
  • HTML 응답
  • HTTP API - MessageBody JSON 응답

HTTP 응답으로 HTML을 반환할 때는 content-type을 text/html 로 지정해야 한다.

 //Conter-Type: text/html;charset=utf-8
        response.setContentType("text/html"); //웹 브라우저가 html 렌더링 하기 위함 (출력은 안되지만 소스보기하면 html 태그가 보임)
        response.setCharacterEncoding("utf-8");

응답 데이터 - API JSON

응답은 크게 세 가지

1. 단순 텍스트
2. HTML
3. message body에 직접 JSON 보내기
// json도 그냥 문자이기 때문에 형태 JSON문자로 바꿔줘야 한다
   private ObjectMapper objectMapper = new ObjectMapper();
   
//{"username":"kim","age":20}
   String result = objectMapper.writeValueAsString(data);

HTTP응답으로 JSON을 반환할 때는 Content-Type을 application/json으로 지정해야 한다.
Jackson 라이브러리가 제공하는 objectMapper.writeVaueAsString() 메서드를 사용해서 JSON문자로 변경할 수 있다.


정리

클라이언트 -> 서버
1. GET 방식 (메세지 바디 데이터 X, 단순 URL)
2. POST - HTML Form

위 두 방식의 파라미터와 URL이 (/url ? username=hello&age=20)이 보낼때는 다르지만
서버입장에서는 똑같기 때문에 그냥 요청파라미터를 읽는다고 퉁침

  1. HTTP message body - 데이터 직접 담아서 요청
  • HTTP API에서 주로 JSON 형식 사용

HTML Form 데이터를 전송할 때는 POST 방식만 가능
(단, 스프링에서는 PUT, PATCH로도 가능하게 해주긴 함) (???)


Reference
김영한 님 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

profile
효율적이고 꾸준하게

0개의 댓글