728x90
HTTP 요청 데이터
- HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법이 3가지가 있다.
- GET - 쿼리 파라미터
- POST - HTML Form
- HTTP message body
HTTP 요청 데이터 - GET (쿼리 파라미터)
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달한다.
- 검색, 필터, 페이징 등에서 많이 사용하는 방식이다.
- 쿼리 파라미터는 URL에 ? 를 시작으로 보낼 수 있다. 추가 파라미터는 & 로 구분하면 된다.
- ex) http://localhost:8080/request-param?username=hello&age=20
- 전달 데이터 : username=hello / age=20
- 서버에서 HttpServletRequest 객체를 통해 쿼리 파라미터를 편하게 조회할 수 있다.
- GET (URL 쿼리 파라미터) 형식으로는 클라이언트에서 서버로 데이터를 전달할 때 HTTP 메시지 바디를 사용하지 않기 때문에 content-type이 없다.
📌 ReqeustParamServlet 클래스
package hello.servlet.basic.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
/**
* 1. 파라미터 전소 기능
* http://localhost:8080/request-param?username=hello&age=20
*
* 2. 동일한 파라미터 전송 가능
* http://localhost:8080/request-param?username=hello&username=kim&age=20
* */
@WebServlet(name="requestParamServlet", urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("[전체 파라미터 조회] - start");
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName+ " = " + request.getParameter(paramName)));
System.out.println("[전체 파라미터 조회 - end]");
System.out.println();
System.out.println("[단일 파라미터 조회]");
String username = request.getParameter("username");
System.out.println("request.getParameter(username) = " + username);
String age = request.getParameter("age");
System.out.println("request.getParameter(age) = " + age);
System.out.println();
System.out.println("[이름이 같은 복수 파라미터 조회]");
System.out.println("request.getParameter(username)");
String[] usernames = request.getParameterValues("username");
for (String name : usernames) {
System.out.println("username = " + name);
}
response.getWriter().write("ok");
}
}
- 실무에서는 파라미터를 전부 조회할 일이 많이 없다.
- 대부분 단일 파라미터 조회를 많이 쓴다.
- request.getParameter()
- 쿼리 파라미터가 username=hello&username=kim 처럼 파라미터 이름은 하나인데, 값이 중복된 경우 request.getParameter() 메서드를 사용한다.
🔍 쿼리 파라미터 조회 메서드
// 단일 파라미터 조회
String uesername = request.getParameter("uesername");
// 파라미터 이름들 모두 조회
Enumeration<String> parameterNames = request.getParameterNames();
// 파라미터를 Map으로 조회
Map<String, String[]> parameterMap = request.getParameterMap();
// 복수 파라미터 조회
String[] usernames = request.getParameterValues("username");
HTTP 요청 데이터 - POST (HTML Form)
- HTML Form을 사용해서 클라이언트에서 서버로 데이터를 전송할 수 있다.
- 주로 회원가입, 상품 주문 등에서 사용한다.
- POST로 요청하기 때문에 데이터를 Http request message body에 쿼리 파라미터 형식으로 전달한다.
- ex) username=hello&age=20
- 메세지 바디의 데이터 형식이 쿼리 파라미터와 동일한 형식이라서 GET 방식과 같은 방법으로 조회할 수 있다.
- 즉, request.getParameter() 메서드는 GET 방식과 POST 방식을 둘 다 지원한다.
- POST HTML Form 형식으로 데이터를 전달하면 HTTP 메시지 바디에 해당 데이터를 포함해서 보내기 때문에 바디에 포함된 데이터가 어떤 형식인지 Content-Type을 반드시 지정해야 한다.
- 예시
- content-type: application/x-www-form-urlencoded
- HTML Form으로 데이터를 전달하는 형식을 application/x-www-form-urlencoded 라고 한다.
- content-type을 pplication/x-www-form-urlencoded으로 적으면 메시지 바디의 데이터 형식이 GET 방식의 쿼리 파라미터 형식과 같아진다.
- 그래서 쿼리 파라미터 조회 메서드( rqeust.getParameter() )를 그대로 사용하면 된다.
- message body : username=hello&age=20
- content-type: application/x-www-form-urlencoded
- Content-Type이란, HTTP 통신에서 전송되는 데이터 타입을 나타내는 header 정보 중 하나다.
- Content-Type은 HTTP 메시지 바디의 데이터 형식을 지정한다.
- 데이터를 받은 쪽에서 Content-Type에 따라 데이터를 어떻게 처리할지 결정한다.
- 데이터를 Content-Type 없이 보내면 데이터를 받는 쪽에서 단순히 텍스트 데이터로 인식한다.
- HTTP 메서드에서 GET 방식은 URL에 쿼리파라미터 형식으로 key=value 형식으로 보내기 때문에 Context-Type이 필요가 없다.
- POST 또는 PUT 방식처럼 메시지 바디에 데이터를 전달할 때 Content-Type이 필요하다.
- 예시
💡 정리
- 클라이언트 입장에서 데이터를 보낼 때 GET 방식으로 URL에 쿼리파라미터로 데이터를 보내느냐 / POST 방식으로 HTML Form으로 데이터를 보내느냐에 따라 데이터를 보내는 방법이 서로 다르다.
- 데이터를 받는 서버 입장에서는 둘 다 형식이 동일하므로 GET, POST 구분 없이 request.getParameter() 메서드로 데이터를 조회하면 된다.
💡 Postman을 이용해서 POST 방식 테스트하기
- Postman 애플리케이션을 이용하여 HTML파일 없이 데이터를 전송할 수 있다.
- POST 전송시 Body 카테고리에서 x-www-form-urlencoded를 체크 해줘야한다.
- Header 카테고리에서 application/x-www-form-urlencoded 인지 확인할 것
HTTP 요청 데이터 - API 메시지 바디
🔍 API 메시지 바디 - 단순 텍스트
- HTTP message body에 데이터를 직접 담아서 요청한다.
- HTTP API에서 주로 사용한다.
- 데이터를 JSON 형식으로 사용한다.
- POST, PUT, PATCH 방식이다.
- HTTP API에서 주로 사용한다.
📌 RequestBodyStringServlet 클래스
package hello.servlet.basic.request;
import org.springframework.util.StreamUtils;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@WebServlet(name="requestBodyStringServlet", urlPatterns = "/request-body-string")
public class RequestBodyStringServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// HTTP 메시지 바디의 데이터를 바이트 코드로 변환
ServletInputStream inputStream = request.getInputStream();
// 바이트 코드를 String 타입으로 변환
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); // 타입 변환시 문자표(Charset)를 UTF-8로 지정할 것
System.out.println("messageBody = " + messageBody);
response.getWriter().write("ok");
}
}
- 단순 텍스트로 받으려면 HTTP 메시지 바디의 데이터를 바이트 코드로 변환하고 String 타입으로 변환했다. String 타입으로 변환시, UFT-8 지정을 꼭 해줘야 한다.
- HTTP 메시지 바디 데이터 → 바이트 코드 → String 타입 (UTF-8 지정)
💡 Postman으로 테스트하기
🔍 API 메시지 바디 - JSON
- 요새는 json 형식을 자주 사용한다.
📌 HelloData
package hello.servlet.basic;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class HelloData {
private String username;
private int age;
}
📌 RequestBodyJsonServlet 클래스
package hello.servlet.basic.request;
import com.fasterxml.jackson.databind.ObjectMapper;
import hello.servlet.basic.HelloData;
import org.springframework.util.StreamUtils;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@WebServlet(name="requestBodyJsonServlet", urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {
// Jackson 라이브러리
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);
// Jackson 라이브러리를 사용해서 JSON 결과를 파싱해서 자바 객체로 변환
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
System.out.println("helloData.username = " + helloData.getUsername());
System.out.println("helloData.age = " + helloData.getAge());
response.getWriter().write("ok");
}
}
- JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 같은 JSON 변환 라이브러리를 사용해야 한다.
- 스프링 부트로 Spring MVC를 선택하면 기본으로 Jackson 라이브러리(ObjectMapper 클래스)를 함께 제공한다.
- HelloData 클래스는 JSON 객체를 클래스로 변환할 때 변환된 정보를 받기 위한 임시 데이터 객체다.
- 지금은 이렇게 Stream을 JSON으로 바꾸고 직접 변환을 해줘야하지만 나중에 Spring MVC를 사용하면 편리하게 사용할 수 있다.
👀 참고 자료
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
https://yunzema.tistory.com/186
https://pygmalion0220.tistory.com/entry/HTTP-Content-Type
728x90
'[ Spring ] > SpringMVC 1편' 카테고리의 다른 글
[Spring] 서블릿으로 회원 관리 웹 애플리케이션 만들기 (0) | 2022.02.17 |
---|---|
[Spring] HttpServletResponse / 응답 데이터 전달하는 방법 (0) | 2022.02.15 |
[Spring] 서블릿 (0) | 2022.02.12 |
[Spring] 자바 웹 기술 역사 (0) | 2022.02.12 |
[Spring] 서버 사이드 렌더링(SSR), 클라이언트 사이드 렌더링(CSR) (0) | 2022.02.11 |