Spring

[Spring] 스프링 MVC 1편, 백엔드 웹 개발 핵심 기술 - 2

haenni 2024. 1. 6. 20:30

👩‍💻 웹 애플리케이션 이해


 

📌HttpServletRequest - 기본 사용

✏️서블릿 기본 

실행 값

  • 서블릿을 사용하기 위해 WebServlet 애노테이션을 사용하고 서블릿의 이름 (name)과 urlPatterns 를 정해준다.
    • 이때 name과 urlPatterns는 똑같아선 안된다.
  • 서블릿은 request 객체를 알아서 만들어주어 HTTP 요청을 보내고, response를 만들어 HTTP 응답을 가져온다.

 

 

✏️Request의 StartLine 정보

출력 값 (원래는 method가 GET이여야지 하지만, Postman을 사용하여 method를 POST로 바꾸었다.)

 

실행 값

 

 

 

✏️Request의 Headers 정보

출력 값

 

Header의 편의 조회

 

 

 

 

✏️Request의 Header의 편의 정보

출력 값
실행 값

 

 

 

 

✏️Request의 기타 정보

출력 값

 

 

 

 

 

 

 

 

 


 

📌HTTP 요청 데이터 - 개요

✏️HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 보내는 방법을 알아보자

 

  • GET - 쿼리 파라미터
    • /url**?username=hello&age=20**
    • 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함하여 전달
    • 예) 검색, 필터, 페이징등에서 많이 사용
  • POST - HTML Form
    • content-type: application/x-www-form-urlencoded
    • 메시지 바디에 쿼리 파리미터 형식으로 전달 
      • username=hello&age=20
    • 회원 가입상품 주문, HTML Form 사용
  • HTTP message body에 직접 데이터를 담아서 전송
    • HTTP API(REST API)에서 주로 사용.
    • 데이터 형식은 주로 JSON 사용
    • POST, PUT,PATCH

 

 

 

 

 

 

 

 

 

 

 


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

✏️Get 쿼리 파라미터를 사용해서 데이터를 클라이언트에서 서버로 전송해보자

:GET 쿼리 파라미터를 사용하여 "메시지 바디 없이" 데이터를 전송할 수 있다.

 

전달 데이터

  • username = hello
  • age = 20
"쿼리 파라미터 사용방법"
쿼리 파라미터는 URL에 다음과 같이 "?"을 시작으로 보낼 수 있다. 추가 파라미터는 "&"으로 구분하면 된다.
ex)http://localhost:8080/request-param?username=hello&age-20

 

 

 

 

✏️Get 쿼리 파라미터를 사용하여 전체 파라미터 조회

실행 결과

 

실행을 하고 URL을 아래처럼 입력해준다.

http://localhost:8080/request-param?username=hello&age=20

실행 값

 

 

 

 

✏️Get 쿼리 파라미터를 사용하여 단일 파라미터 조회

결과 값

 

실행 값

 

 

 

 

 

✏️Get 쿼리 파라미터를 사용하여 이름이 같은 복수 파라미터 조회

:Get 쿼리 파라미터는 하나의 파라미터(ex- username)에 여러 값(ex - "kim", "min")을 넘길 수 있다.

예를 들어서
"http://localhost:8080/request-param?username=hello&age=20&username=hello2"
와 같이, username이라는 하나의 파라미터에 여러 값을 넣게 되면 어떻게 될까?
(위의 예제는 username이라는 하나의 파라미터에 hello와 hello2 두개의 값을 넣었다)
우선순위가 높은 값이 나오게 된다. 즉, 하나의 값만 출력되게 된다

이럴때는 request.getParameterVlaues()와 같은 메서드를 사용해서 값을 배열로 받아야 한다.
( request.getParameterVlaues("username") 메서드는 username 파라미터의 값들을 배열로 받아준다.)

 

 

 

"http://localhost:8080/request-param?username=hello&age=20&username=hello2"을 넣었을 때,

출력 값

 

"처음 본 자바 문법 정리" 

for (Stirng name : usernames) {}

 (String name : usernames) 향상된 for 문(Enhanced for loop)입니다. 이 문법은 배열이나 컬렉션과 같은 Iterable 객체의 모든 요소에 대해 간편하게 반복할 수 있도록 도와줍니다.
위의 예제를 보면 for(String name : usernames) {...}는 향상 된 for 문으로, usernames 배열의 각 요소를 순회합니다.
각 순회마다 현재 요소를 name 변수에 할당하고, 반복문 안의 코드 블록을 실행합니다.

 

 

 

 

 

 

 

 

 

 

 


📌HTTP 요청 데이터 - POST HTML Form

✏️HTML Form을 사용해서 클라이언트에서 서버로 데이터를 전송해보자.

:HTML Form 방법은 "메시지 바디"에 쿼리 파라미터 형식으로 데이터를 전달하며, 주로 회원가입, 상품 주문 등에서 사용하는 방법이다.

 

 

basic 폴더를 만든 뒤, 그 안에 hello-form이라는 html을 만들어 해당 html 코드를 작성하였다.

이후 http://localhost:8080/basic/hello-form.html에 접속해보면 위와 같은 웹 페이지가 뜬다.
username에 "kim"을 입력하고, age에 "20"을 넣고 전송해보자.

 

실행 값

 

java 코드

 

그러면 웹 페이지가 "http://localhost:8080/request-param"로 이동하게 되면서, 화면에 내가 입력했던 username의 이름이 뜨게 된다. 이는 hello-form.html의 action을 보면, post 메서드로 값을 "/request-param"으로 전송하도록 되어있다.
"/request-param"은 전 시간 파라미터 조회하는 페이지를 만들기 위해 작성한 java 코드이다. 그 Java코드에 response.getWriter().write(username);을 해주었기 때문에 우리가 전송했던 "kim"이라는 이름이 화면에 출력 된 것이다.

 

 POST의 HTML Form을 전송하면 웹 브라우저는 다음 형식으로 HTTP 메시지를 만든다.
"요청 URL": "http://localhost:8080/request.param"
"content-type":"application/x-www-form-urlecoded"
"message body": "username=hello&age=20"

➜ "application/x-www-form-rulencoded"형식은 앞서 GET에서 살펴본 쿼리 파라미터 형식과 같다. 따라서 "쿼리 파라미터 조회 메서드를 그대로 사용"하면 된다.
서버 입장에서는 둘의 형식이 동일하므로, "request.getParameter()"로 편리하게 구분없이 조회할 수 있다.

결론은, "request.getParameter()"는 GET URL 쿼리 파라미터 형식도 지원하고, POST HTML Form 형식도 지원한다.

 

 

 

 

✏️HTML Form을 만들기 귀찮을 때, Postman을 사용하자!

실행 값

x-www-form-urlencoded를 선택한 뒤 body에 key값으로 username과 age를 넣어주고, Vlues 값으로 haen과 30을 각각 넣어준다.

그럼 아래처럼 Pretty를 보았을 때 haen이 출력되는 것을 볼 수 있다. 또, 출력값을 보면 아래와 같이 값이 들어가있다.

 

 

 

 

 

 

 

 

 

 

 


📌HTTP 요청 데이터 - API 메시지 바디 (단순 텍스트)

✏️HTTP API를 사용해서 클라이언트에서 서버로 데이터를 전송해보자.

: "메시지 바디"에 원하는 데이터를 직접 담아서 서버에 전송

  • HTTP API에서는 주로 JSON을 사용
  • POST, PUT, PATCH

 


ㅇ    request.getInputStream() ➜  메시지 바디 내용을 바이트 코드로 얻을 수 있다.
ㅇ   StreamUtils.copyToString(inputStream, StanderdCharsetsl.UTF_8); 
➜   inputStream에 있는 바이트를 String으로 바꾸어준다.

이후 messageBody를 출력해보자.

 

결과 값

 

Postman을 통하여 메시지 바디의 내용을 Hello!라고 적었다.
response.getWriter().write("ok"); 때문에 Pretty에 ok라는 문자가 출력된 것을 알 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 


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

✏️HTTP API를 사용해서 클라이언트에서 서버로 데이터를 전송해보자.

:HTTP API에서 주로 사용하는 JSON 형식으로 데이터를 전달해보자.

  • "JSON 형식 전송"
    • POST http://localhost:8080/request.body-json
    • content-type:"application/json"
    • message body:{"username": "hello", "age":20}
    • 결과: messageBody = {"username": "hello", "age":20}

ㅇ    request.getInputStream() ➜  메시지 바디 내용을 바이트 코드로 얻을 수 있다.
ㅇ   StreamUtils.copyToString(inputStream, StanderdCharsetsl.UTF_8); 
➜   inputStream에 있는 바이트를 String으로 바꾸어준다.

이후 messageBody를 출력해보자.

실행 결과

 

Postman을 통하여 형식은 JSON으로 바꾼뒤 바디를 넣어줬다.
response.getWriter().write("ok"); 때문에 Pretty에 okay라는 문자가 출력된 것을 알 수 있다.

 

 

 

✏️JSON 값 가져오기

 

 

HelloData라는 class를 하나 생성한 뒤, username이라는 필드와 age라는 필드를 생성해준다.

필드로 ObjectMapper 타입의 객체를 생성한다.

실행 결과

objectMapper.readValue(messageBody, HelloData.class); 를 통해서 messageBody의 Json을 읽고 helloData 변수에 넣어준다.

helloData.getUsername()과 get.Age()로 값을 출력해준다.

전체 코드

 

참고

JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 같은 JSON 변환 라이브러리를 추가해서 사용해야 한다. 스프링 부트로 Spring MVC를 선택하면 기본적으로 Jackson 라이브러리("ObjectMapper")를 함께 제공한다.

나중에 MVC를 사용하게 되면 훨씬 간결하게 쓸 수 있다. 이건 나중에 MVC 강의에 자세히 들어가게 되면 배우게 된다.

 

 

 

 

 

 

 

 

 

 


📌HttpServletResponse - 기본 사용법

✏️HttpServletResponse 역할

  • "HTTP 응답 메시지 생성"
    • HTTP 응답코드 지정 (state (404, 201 등등) )
    • 헤더 생성
    • 바디 생성
  • "편의 기능 제공"
    • Content-Type, 쿠키, Redirect

 

전체 코드

ㅇ    response.setTatus(HttpServletResponse.SC_OK); ➜  응답 상태 코드를 넣을 수 있음
        ㅇ respont.setTatus(200); 이라고 상태코드를 넣어도 되지만, HttpServletResponse를 들어가보면 수 많은 상태코드가
             상수로 저장되어있다. 상수로 적어주는게 더 좋다.
ㅇ   response.setHeader("Content-Type", "text/plain;charset=utf-8""); ➜ 헤더의 ContentType 을 직접 지정
ㅇ   response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");  ➜ 헤더의 캐시 직접 지정
ㅇ   response.setHeader("Pregma", "no-cache");   ➜ 헤더의 캐시 직접 지정
ㅇ   response.setHeader("my-haeder", "hello"); ➜ 내가 만든 임의의 헤더  

 

실행 시 관리자 코드를 보면 위와 같이 Response Headers 부분에 내가 지정한 헤더들이 다 잘 들어갔음을 알 수 있다.

 

 

✏️상태코드를 변경해보자

: 상태코드를 SC_BAD_REQUEST(= 400)으로 변경해보자.

상태코드 변경

 

 

실행 시 관리자 코드를 보면 Status가 400으로 뜨는 것을 알 수 있다.

 

 

 

✏️Content에 대한 편의 기능

response.setHeader("Content-Type", "text/plain;charset=utf-8");이 아니라

response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
와 같이 쓸 수도 있다.

response.setContentLength(2);는 생략 가능하다 (메시지 바디의 길이)

 

 

 

 

✏️Cookie에 대한 편의 기능

Cookie라는 객체를 만들고 setMaxAge(유효시간) 해서 addCookie로 response에 넣어주면 위에 주석처리한 코드와 동일하게 작용한다.

 

 

 

 

✏️Redirect에 대한 편의 기능

 

Status Code를 302라고 설정할 것이고, Location을 hello-form.html으로 보낼것이다.

sendRedirect("url")을 넣어주면 된다.

Status Code가 300대이면 Rediect가 가능하다. 응답 코드가 300대일 경우 Location의 경로로 홈페이지가 이동하게 된다.
이로인해 "localhost:8080/response-header"로 접속을 해도, 아래의 사진처럼 지정한 "http://localhost:8080/basic/hello-form.html" 경로로 들어가게 된다.

 

 

 

 

 

 

 

 

 

 


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

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

  • 단순 텍스트 응답
    • 앞에서 살펴봄('writer.println("ok")')
  • HTML 응답
  • HTTP API - MessageBody JSON 응답

 

 

 

 

✏️HttpServletResponse - HTML 응답

➜ response.setContextType("text/html")
➜ response.setCharacterEncoding("utf-8");
: 우선 메시지 바디의 타입을 무조건 text/html으로 변경해주어야 한다. 또한, setCharacterEncoding()으로 "utf-8"을 지정해주어야 한글을 넣어도 깨지지 않는다.

그리고 writer 객체를 만들어 html 문법을 맞춰서 내용을 넣어준 뒤, "http://localhost:8080/response-html"에 접속해보았다.

 

 

소스보기

위와 같이 html에 작성한 "안녕?"이 웹 페이지에 뜨게 된다.
소스보기를 하면 우리가 작성했던 html이 뜨는 것을 확인할 수 있다.

 

 

 

✏️HttpServletResponse - API JSON

 

➜ response.setContextType("text/json")
➜ response.setCharacterEncoding("utf-8");
: 우선 메시지 바디의 타입을 무조건 text/json으로 변경해주어야 한다. 또한, setCharacterEncoding()으로 "utf-8"을 지정해주어야 한글을 넣어도 깨지지 않는다.

HelloData 객체를 생성하고 setUsername과 setAge를 통해서 age와 username필드에 값을 넣어준다.
objectMapper 객체를 생성하고, objectMapper에 writeValuseAsString(helloData)를 사용하여 String으로 값을 넣어준 뒤, response.getWriter().write(result);로 웹 사이트에 표시한다.

 

웹 사이트 실행