Host~ Content-Type 부분이 헤더정보
HttpServeletRequest 객체는 http요청메시지를 편리하게 읽어들이는 기능에다가 부가기능을 제공한다.
HttpServletRequest - 기본 사용법
http요청메시지 첫번째 라인에 나오는 정보들, HttpServletRequest객체를 이용하여 가져오기
@WebServlet(name = "requestHeaderServlet",urlPatterns = "/request-header")
public class RequestHeaderServlet extends HttpServlet { //헤더정보관련해서 공부용 서블릿
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
printStartLine(request);
}
private static void printStartLine(HttpServletRequest request) {
System.out.println("--- REQUEST-LINE - start ---");
System.out.println("request.getMethod() = " + request.getMethod()); //get,post와 같은 http메소드를 가져온다.
System.out.println("request.getProtocol() = " + request.getProtocol()); // HTTP/1.1와 같은 http프로토콜정보를 가져온다.
System.out.println("request.getScheme() = " + request.getScheme());
/*사용할 프로토콜을 말하며, 리소스에 어떻게 요청, 접근할 것인지를 명시합니다.
웹에서 주로 HTTP 프로토콜을 사용합니다.
출력 예)http
*/
System.out.println("request.getRequestURL() = " + request.getRequestURL());
// http://localhost:8080/request-header 처럼 전체 url을 출력
System.out.println("request.getRequestURI() = " + request.getRequestURI());
// /request-header와 같이 뒷부분만 출력
System.out.println("request.getQueryString() = " + request.getQueryString());
// 쿼리스트링이 존재하면 가져온다 예) username=hi
System.out.println("request.isSecure() = " + request.isSecure());
//https 사용 유무
System.out.println("--- REQUEST-LINE - end ---");
System.out.println();
}
}
HttpServletRequest객체를 이용하여 헤더이름 가져오기
옛날방식
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println("headerName = " + headerName);
}
System.out.println("--- Headers - end ---");
System.out.println();
}
요즘방법으로 헤더이름 출력하는법
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
request.getHeaderNames().asIterator().forEachRemaining(headerName -> System.out.println(
"headerName = " + headerName));//요즘방법으로 헤더들 출력하는법.
System.out.println("--- Headers - end ---");
System.out.println();
}
HttpServletRequest객체를 이용하여 헤더정보 가져오기
//Header 편리한 조회
private void printHeaderUtils(HttpServletRequest request) {
System.out.println("--- Header 편의 조회 start ---");
System.out.println("[Host 편의 조회]");
System.out.println("request.getServerName() = " + request.getServerName()); //Host 헤더
System.out.println("request.getServerPort() = " + request.getServerPort()); //Host 헤더
System.out.println();
System.out.println("[Accept-Language 편의 조회]");
request.getLocales().asIterator()
.forEachRemaining(locale -> System.out.println("locale = " +
locale));
System.out.println("request.getLocale() = " + request.getLocale());
System.out.println();
System.out.println("[cookie 편의 조회]");
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
System.out.println();
System.out.println("[Content 편의 조회]");
System.out.println("request.getContentType() = " + request.getContentType());
System.out.println("request.getContentLength() = " +request.getContentLength());
System.out.println("request.getCharacterEncoding() = " + request.getCharacterEncoding());
System.out.println("--- Header 편의 조회 end ---");
System.out.println();
}
getLocales()를 하게되면 웹브라우저가 선호하는 언어를 순서대로 보내준다.
getLocale()를 하게되면 웹브라우저가 받을수있는 언어중 가장 선호하는 언어를 보내준다.
여기서는 localhost:8080/request-header로 get방식으로 url를 호출했기에 .getContentType()를 했을때 null이 나온다.(바디에 데이터가 없으니까) http://localhost:8080/request-header?username=kim이런식으로 쿼리스트링을 보내도 getContentType의 값은 null이다. contentType은 쿼리가아닌 body로 담겨오는값에 대한 정보이기 때문이다.
테스트하려면 Postman으로 post방식을 사용해서 보내본다.
HttpServletRequest객체를 이용하여 기타정보 가져오기
private void printEtc(HttpServletRequest request) {
System.out.println("--- 기타 조회 start ---");
System.out.println("[Remote 정보]"); //내부적으로 네트워크 커넥션정보
System.out.println("request.getRemoteHost() = " +
request.getRemoteHost()); //
System.out.println("request.getRemoteAddr() = " +
request.getRemoteAddr()); //
System.out.println("request.getRemotePort() = " +
request.getRemotePort()); //
System.out.println();
System.out.println("[Local 정보]"); //서버정보
System.out.println("request.getLocalName() = " +
request.getLocalName()); //
System.out.println("request.getLocalAddr() = " +
request.getLocalAddr()); //
System.out.println("request.getLocalPort() = " +
request.getLocalPort()); //
System.out.println("--- 기타 조회 end ---");
System.out.println();
}
http요청 데이터
http 요청메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법을 알아본다.
3가지 방법
1. get방식 -> 메시지 바디없이, URL의 쿼리 파라미터를 이용해서 데이터를 전달한다.
2. post방식 -> html form으로 보내는방법은 메시지 바디에 쿼리 파라미터 형식으로 전달한다. contentType은 application/x-www-form-urlencoded이다. 이 type을 보면 html form으로 데이터를 전송하고 있다고 보면된다.
+ 메시지바디에 쿼리 파라미터 형식으로 전달한다.
3. HTTP message body에 데이터를 직접 담아서 요청하는 방법
http api(rest api)에서 주로 사용하고 데이터 형식은 JSON,XML,TEXT가 있는데 주로 JSON을 사용한다.
POST,PUT,PATCH를 다 사용가능하다.
JSON일 경우 contentType은 application/json이다.
HTTP요청데이터 - GET 쿼리 파라미터(쿼리스트링)
@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("파라미터 전체조회");
request.getParameterNames().asIterator().forEachRemaining(paramName -> System.out.println( //모든 파라미터이름을 받아, 파라미터 값을 출력
"paramName = " + paramName + ", paramValue = " + request.getParameter(paramName)));
//파라미터 단일조회
System.out.println("파라미터 단일조회");
String userName = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("userName = " + userName);
System.out.println("age = " + age);
//http://localhost:8080/request-param?username=kil&age=10&username=kil22 와 같이 파라미터이름이 username으로 같은데 값이 2번들어가는경우도있다.
//이름이 같은 복수 파라미터 조회
System.out.println("파라미터 이름이 같은 복수 파라미터 조회");
String[] usernames = request.getParameterValues("username"); //파라미터 이름이 username인 모든 파라미터값들 가져온다.
for (String username : usernames) {
System.out.println("username = " + username);
}//만약 단일조회로 꺼냈다면 먼저들어간 값이 출력된다.
response.getWriter().write("OK"); //응답메시지를 넣어준다.
}
}
HTTP요청 데이터 - POST HTML Form
테스트를 위해 form 형식 html 파일 추가해준다. webapp폴더 밑에 basic폴더를 만들어 추가해주었다.
url를 다음과 같이 위치를 이용해 접근가능하다.
http://localhost:8080/basic/hello-form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/request-param" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
</body>
</html>
hello-form.html의 내용이다.
action = "/request-param"을 보면 form안의 데이터가 /request-param으로 보내진다는것을 알 수 있다.
하지만 url을 /request-param으로 보내면 위에서만든
@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("파라미터 전체조회");
request.getParameterNames().asIterator().forEachRemaining(paramName -> System.out.println( //모든 파라미터이름을 받아, 파라미터 값을 출력
"paramName = " + paramName + ", paramValue = " + request.getParameter(paramName)));
//파라미터 단일조회
System.out.println("파라미터 단일조회");
String userName = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("userName = " + userName);
System.out.println("age = " + age);
//http://localhost:8080/request-param?username=kil&age=10&username=kil22 와 같이 파라미터이름이 username으로 같은데 값이 2번들어가는경우도있다.
//이름이 같은 복수 파라미터 조회
System.out.println("파라미터 이름이 같은 복수 파라미터 조회");
String[] usernames = request.getParameterValues("username"); //파라미터 이름이 username인 모든 파라미터값들 가져온다.
for (String username : usernames) {
System.out.println("username = " + username);
}//만약 단일조회로 꺼냈다면 먼저들어간 값이 출력된다.
response.getWriter().write("OK"); //응답메시지를 넣어준다.
}
}
이 서블릿이 값을 받아 비즈니스 로직을 실행할텐데,
비즈니스 로직안에서는 파라미터를 받아 값을 출력해보는 코드가있다.
form을 이용해서 데이터를 보낸것은 내용은 물론 쿼리파라미터 형식이지만 바디에 담겨져 있는데 결과는 어떻게될까
클라입장에서는 데이터를 보내는 두방식이 차이가 있지만, 서버입장에서는 결국 쿼리파리미터형식으로 들어오므로,
GET url 쿼리파리미터 형식이나 POST html form 형식이나 둘다 getParameter로 편리하게 조회가능.
HTTP 요청 데이터 - API 메시지 바디 -단순 텍스트 보내보기
지금까지 위의 2가지 방식 -> GET url 쿼리파라미터 방식, POST html form 방식은 웹브라우저에서 일반적으로 하는방식이고 이제 배울 API방식은 내가 원하는 데이터를 직접 바디에 담아 서버에 보내는 방식
HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
@WebServlet(name = "requestBodyStringServlet",urlPatterns = "/request-body-string")
public class RequestBodyStringServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletInputStream inputStream = request.getInputStream(); // inputStream으로 메시지 바디의 내용을 바이트코드로 얻을 수 있다.
String messageBody = StreamUtils.copyToString(inputStream,
StandardCharsets.UTF_8);// 받은 바이트코드를 스트링으로 바꿔준다 , 인코딩 정보도 같이 보내준다.
System.out.println("messageBody = " + messageBody);
response.getWriter().write("OK");
}
}
Http 요청데이터 - API 메시지바디 - JSON
일반적으로는 json형식으로 데이터를 주고받기때문에 json으로도 해보자.
json형식 데이터는 파싱을 해서 사용해야한다.
json 파싱을 위한 객체를 하나 생성해준다.
@WebServlet(name = "requstBodyJsonServlet",urlPatterns = "/request-body-json")
public class RequstBodyJsonServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletInputStream inputStream = request.getInputStream(); //바디에 있는 데이터를 가져오는것은 inputStream으로 똑같다.
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); //inputStream을 이용해서 바디에 있는 내용을 바이트코드로 받았고, 그걸 STring으로 변환
System.out.println("messageBody = " + messageBody);
}
}
객체로 json 파싱하기
@WebServlet(name = "requstBodyJsonServlet",urlPatterns = "/request-body-json")
public class RequstBodyJsonServlet extends HttpServlet {
//json파싱을 하기위해서는 라이브러리가 필요하다. 스프링부트는 기본적으로 jackson이라는 json파싱라이브러리를 가지고있다.
private ObjectMapper objectMapper = new ObjectMapper(); //json 파싱을 도와주는 objectMapper 객체 생성
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletInputStream inputStream = request.getInputStream(); //바디에 있는 데이터를 가져오는것은 inputStream으로 똑같다.
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); //inputStream을 이용해서 바디에 있는 내용을 바이트코드로 받았고, 그걸 STring으로 변환
//String으로 변환까지해서 바디에 적은 json형태 그대로 데이터를 받았다. 이걸 HelloData 객체를 이용하여 파싱해보자.
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class); //readValue에 json형식인 String값,파싱할 클래스를 전달해주면
//해당 객체로 json을 파싱해준다.
System.out.println("helloData.getUsername() = " + helloData.getUsername());
System.out.println("helloData.getAge() = " + helloData.getAge());
response.getWriter().write("OK");
}
}
객체에 json값을 매핑해줘서 이름이 ObjectMapper인거같다.
ObejctMapper의 readValue메소드를 이용해서 전달한 클래스의 객체를 생성해서 그 객체에 매핑해준다.
HttpServletResponse 기본 사용법
@WebServlet(name = "responseHeaderServlet",urlPatterns = "/response-header")
public class ResponseHeaderServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//[status-line] http응답메시지에서 첫번째줄을 status line이라한다.
response.setStatus(HttpServletResponse.SC_OK); //setStatus()로 http 응답코드를 넣을수있다, 직접 숫자를 넣을수도 있지만 상수로 저장된 변수를 이용하는게 좋다
// 기본 성공 응답코드값은 200이다.
//[response-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"); //이렇게 내가 원하는 임의의 헤더를 만들어서 넣을수도 있다.
PrintWriter writer = response.getWriter();
writer.println("ok");
}
}
응답메시지 Header값 세팅 다른 편의 메소드들
private void content(HttpServletResponse response) {
//Content-Type: text/plain;charset=utf-8
//Content-Length: 2
//위의 헤더값들을 지정하고 싶을때
//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"); setHeader 메소드를 이용하여 쿠기설정이 가능하기도 하고
Cookie cookie = new Cookie("myCookie", "good"); //쿠키 객체를 만들어서 응답메시지에 추가가능
cookie.setMaxAge(600); //600초
response.addCookie(cookie); //만든 쿠키 추가
}
쿠키가 잘들어간것을 확인가능.
서블릿response 리다이렉트 메소드
private void redirect(HttpServletResponse response) throws IOException {
//Status Code 302 -> 상태코드를 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응답메시지의 헤더,start-line,상태코드,쿠키 등에 대해서 알아봤고
이번에는 응답데이터부분에 알아본다.
위에서 계속
PrintWriter writer = response.getWriter();
writer.println("ok");
response.getWriter().write("OK");
이렇게 2가지 방식으로 응답 데이터로 단순텍스트를 전달했었다.
html 응답하는 방법.
@WebServlet(name = "responseHtmlServlet",urlPatterns = "/response-html")
public class ResponseHtmlServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//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>");
}
}
응답데이터에 직접 html코드를 넣어주면 어떻게될까.
소스보기를 하게되면
http 응답 데이터 - API JSON
일반적으로 api의 응답데이터로 json을 많이 보내는데 그방법에 대해 알아본다.
@WebServlet(name = "responseJsonServlet",urlPatterns = "/response-json")
public class ResponseJsonServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper(); //이 예제에서는 json으로 변환하기 위함
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Content-Type : application/json
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
//HelloData 객체에 값을 담는다.
HelloData helloData = new HelloData();
helloData.setUsername("kim");
helloData.setAge(20);
//HelloData 객체에 담긴값을 Json으로 바꿔야한다. -> { "username" : "kim" , "age" : 20} 이런식으로 바꿀것이다.
//JSON 형식의 값을 파싱해서 객체에 매핑했을때 jackson라이브러리의 ObjectMapper 객체가 필요했듯이
// 그 반대인 객체 -> Json도 ObjectMapper를 사용한다.
String result = objectMapper.writeValueAsString(helloData); //writeValueAsString은 객체에 담긴 값을 json형태의 String값으로 뽑아낸다.
// System.out.println("result = " + result); // result = {"username":"kim","age":20}
response.getWriter().write(result);
}
}
정리
http 요청메시지를 이용해서 클라이언트가 서버로 데이터를 보내는 방법은 3가지가있다.
1. GET url 쿼리파라미터를 이용
2. POST html-form 방식 (POST방식으로만 된다)
3. HTTP message body에 데이터를 직접 넣어서 요청 (API에 주로사용하고, JSON형식의 데이터를 주로쓴다 , POST,PUT,PATCH 방식을 사용할 수 있다.)
'인프런 > 스프링 MVC 1편' 카테고리의 다른 글
6)스프링 MVC (구조이해),핸들러 매핑과 핸들러 어댑터,뷰 리졸버 (0) | 2023.01.18 |
---|---|
5)MVC 프레임워크 만들어보기(리팩토링하면서 버전업 v1~v5) (0) | 2023.01.17 |
4)서블릿,JSP,MVC패턴 적용 (0) | 2023.01.16 |
2)서블릿,서블릿컨테이너 (0) | 2023.01.13 |
1)웹서버,웹 어플리케이션 서버,웹 시스템 구성,서블릿,멀티스레드,서버사이드 렌더링,서버 사이드 렌더링 (0) | 2023.01.13 |
댓글