1. Hello 서블릿
서블릿은 톰캣 같은 웹 어플리케이션 서버를 직접 설치하고, 그 위에 서블릿 코드를 클래스 파일로 빌드해서 올린 다음, 톰캣 서버를 실행하면 된다. 해당 과정은 매우 번거롭지만 스프링 부트는 톰캣 서버를 내장하여 톰캣 서버 설치 없이 편리하게 서블릿 코드를 실행할 수 있다.
@ServletComponentScan
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
- 먼저 위의 스프링부트 실행 메인 메서드에 @ServletComponentScan을 붙여야 한다. 그러면 스프링이 현재 패키지를 포함하여 하위 패키지를 모두 뒤져서 서블릿을 모두 찾아서 서블릿을 등록할 수 있도록 도와준다. 즉, @ServletComponentScan은 서블릿 자동 등록을 위한 어노테이션이다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("request = "+request);
System.out.println("response = "+response);
String username = request.getParameter("username");
System.out .println("username = "+username);
response.setContentType("text/plain"); // 텍스트를 보낼 거임.
response.setCharacterEncoding("utf-8"); // 인코딩은 utf-8 방식임.
response.getWriter().write("hello "+username);
}
}
- 서블릿을 만드려면 HttpServlet을 상속받아야 한다. 또한 @WebServlet 어노테이션을 사용하여 name과 urlPatterns를 지정해야 한다.
- HttpServletRequest와 HttpServletResponse는 인터페이스다. 스프링 부트에서 request와 response 객체를 받아보면 아래와 같은 결과를 얻는다.
"request = org.apache.catalina.connector.RequestFacade@4d6986b7"
"response = org.apache.catalina.connector.ResponseFacade@3c6825d"
톰캣 등의 was 서버는 HttpServletRequest, Response의 구현체를 따로 만드는 것이다. 아파치의 경우 위와 같이 RequestFacade, ResponseFacade 구현체를 활용한다. - 지정한 url 패턴에서 "?"를 기준으로 오른쪽 내용들은 파라미터로 전달된다. 이 경우 request 객체의 getParameter을 통해서 가져올 수 있다. 예를 들어, "/hello?username=nam"요청을 보냈다면 getParameter("username")을 통해 "nam"이라는 스트링을 가져올 수 있다.
- response.getWriter().write()를 통해 바디에 원하는 내용을 넣을 수 있다.
위 코드를 작성한 후 "http://localhost:8080/hello?username=nam" 결과를 보내면 아래와 같은 화면을 띄워준다.
만약 편리하게 http 요청 메시지를 다 보고 싶다면 [src]→[main]→[resources]→[application.properties]에 들어가서 아래 내용을 작성하자.
- logging.level.org.apache.coyote.http11=debug
그러면 이전과 동일한 요청을 보낼 때 터미널에 아래와 같은 내용이 발생한다.
2023-09-09T16:37:30.470+09:00 DEBUG 22036 --- [nio-8080-exec-4] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [1129]
2023-09-09T16:37:30.471+09:00 DEBUG 22036 --- [nio-8080-exec-4] o.a.coyote.http11.Http11InputBuffer : Received [GET /hello?username=nam HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: username-localhost-8888="2|1:0|10:1693284885|23:username-localhost-8888|192:eyJ1c2VybmFtZSI6ICJjYmE0OWZiMTJkZmE0YzE3YWYxMDE0MjQ0YzIyMWFjNCIsICJuYW1lIjogIkFub255bW91cyBBb2VkZSIsICJkaXNwbGF5X25hbWUiOiAiQW5vbnltb3VzIEFvZWRlIiwgImluaXRpYWxzIjogIkFBIiwgImNvbG9yIjogbnVsbH0=|a969610c2df6e6786e2f30475272829802c6d234989b4e38880d183c8faf49aa"; _xsrf=2|444914c9|5bce92ae338c9a2267cef836580c1c7c|1693284885
]
request = org.apache.catalina.connector.RequestFacade@550d6b72
response = org.apache.catalina.connector.ResponseFacade@5bca8fa3
username = nam
2023-09-09T16:37:30.479+09:00 DEBUG 22036 --- [nio-8080-exec-4] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [1129]
2023-09-09T16:37:30.480+09:00 DEBUG 22036 --- [nio-8080-exec-4] o.a.coyote.http11.Http11InputBuffer : Received []
2023-09-09T16:37:30.481+09:00 DEBUG 22036 --- [nio-8080-exec-4] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@6aaf5dd5:org.apache.tomcat.util.net.NioChannel@57a2fc28:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8080 remote=/[0:0:0:0:0:0:0:1]:62213]], Status in: [OPEN_READ], State out: [OPEN]
- 하지만 이런 것을 운영서버에 넣는 것은 고민해 봐야 한다. 왜냐하면 운영서버에 이렇게 모든 요청 정보를 다 남기면 성능 저하가 될 수 있기 때문이다. 개발 단계에서만 적용하도록 하자.
2. HttpServletRequest
개발자는 HTTP 요청 메시지를 직접 파싱해도 되지만 이는 매우 불편하다. 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용하도록 개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 HttpServletRequest 객체에 담아준다. 다음과 같은 HTTP 요청 메시지가 있다고 하자.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
...
- 가장 처음을 START LINE이라고 하며 HTTP 메소드, URL, 쿼리 스트링, 스키마/프로토콜 정보가 들어간다.
- Host, Content-Type 등을 헤더 정보라고 부른다.
- 그 아래 username, age 등의 정보가 있는 부분을 바디라고 한다. 바디는 form 파라미터 형식이 될 수 있고, message body 데이터를 직접 조회할 수도 있다.
HttpServletRequest 객체는 위와 같은 요청 메시지를 편리하게 읽을 뿐만 아니라 부가적인 기능도 제공한다.
- 임시 저장소 기능: HTTP 요청의 시작부터 끝날때까지 유지되는 임시 저장소 기능을 수행한다.
- request.setAttribute(name, value): 이 메서드를 사용하면 이 HTTP 요청 메시지가 살아 있는 동안 get으로 해당 값을 꺼내서 사용할 수 있다.
- request.getAttribute(name): 위처럼 저장한 친구들을 꺼낼 때 사용한다.
- 세션 관리 기능: 로그인 같은 것을 하면, 로그인을 한 상태를 유지해야하는데 세션이라는 기능을 사용해야 한다.
- request.getSession(create:true)
어쨋든 HttpServletRequest든 HttpServletResponse든 이 객체들이 HTTP 요청 메시지, HTTP 응답 메시지를 편리하게 사용하도록 도와준다는 것이다. 따라서 이 기능들에 대해 깊이있는 이해를 하려면 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);
printHeaders(request);
printHeaderUtils(request);
printEtc(request);
}
...
}
이때 printStartLine 메서드의 코드는 다음과 같다.
private void printStartLine(HttpServletRequest request) {
System.out.println("--- REQUEST-LINE - start ---");
System.out.println("request.getMethod() = " + request.getMethod()); //GET
System.out.println("request.getProtocol() = " + request.getProtocol()); //HTTP/1.1
System.out.println("request.getScheme() = " + request.getScheme()); //http
// http://localhost:8080/request-header
System.out.println("request.getRequestURL() = " + request.getRequestURL());
// /request-header
System.out.println("request.getRequestURI() = " + request.getRequestURI());
//username=hi
System.out.println("request.getQueryString() = " + request.getQueryString());
System.out.println("request.isSecure() = " + request.isSecure()); //https 사용 유무
System.out.println("--- REQUEST-LINE - end ---");
System.out.println();
}
결과는 아래와 같다.
printHeaders 메서드의 코드는 다음과 같다.
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
// // 옛날 방식
// // getHeaderNames: http 요청 메시지의 모든 헤더 정보를 다 꺼내서 출력할 수 있음.
// Enumeration<String> headerNames = request.getHeaderNames();
// while (headerNames.hasMoreElements()) {
// String headerName = headerNames.nextElement();
// System.out.println(headerName + ": " + headerName);
// }
// 최신 방식
request.getHeaderNames().asIterator()
.forEachRemaining(headerName -> System.out.println(headerName+": "+headerName));
request.getHeader("host"); // host 정보 얻을 수 있음.
System.out.println("--- Headers - end ---");
}
이때 결과는 다음과 같다.
header에 대한 편리한 조회를 위해서는 아래와 같은 방식도 사용한다.
//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();
}
결과는 다음과 같다.
마지막으로 기타적인 정보를 확인하기 위한 printEtc 메서드는 다음과 같다.
//기타 정보
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();
}
결과는 다음과 같다.
3. Http 요청 데이터
HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법에는 3가지 방법이 있다.
- GET - 쿼리 파라미터
- "(url)?username=nam&age=20" 형식
- 메시지 바디 없이 url의 쿼리 파라미터에 데이터를 포함해 전달한다.
- 검색, 필터, 페이징 등에서 많이 사용한다.
- POST - HTML Form
- content-type: x-www-form-urlencoded (content-type이란 바디에 대한 정보에 대해 설명해주는 것이다.)
- 위와 같이 content-type을 통해 전달되는 정보는 html form을 통해 전달된다고 보면된다. 그리고 메시지 바디에 쿼리 파라키터 형식으로 전달된다. 바디에는 "username=nam&age=20" 형식으로 작성된다.
- 회원 가입, 상품 주문 등에 사용한다.
- HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에 주로 사용한다. JSON, XML, TEXT 정보를 그대로 담아서 클라이언트에서 서버로 전달을 한다. 최근에는 JSON을 많이 사용한다.
- POST, PUT, PATCH 등에서 모두 사용할 수 있다.
4. Get 쿼리 파라미터
먼저 Get 쿼리 파라미터를 통해 데이터를 전달해보자. 메시지 바디 없이 URL의 "쿼리 파라미터"로 데이터를 전달할 때 URL 옆에 ?붙여서 데이터를 전달할 수 있다. 단, 파라미터가 여러 개인 경우 &로 구분하면 된다.
- http://localhost:8080/query-param?username=nam&age=22
이러한 방식은 검색, 필터 등에 많이 사용한다. 아래는 쿼리 파라미터로 전달된 데이터들을 활용한 예시 코드다.
@WebServlet(name = "queryParamServlet", urlPatterns = "/query-param")
public class QueryParamServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 이와 같이 사용하면 모든 파라미터를 가져올 수 있음.
* paramName: 이름(key)을 꺼냄 / request.getParameter(paramName): 키에 해당하는 값을 가져옴.
*/
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> System.out.println(paramName+": "+request.getParameter(paramName)));
/*
* 아래는 request.getParamter를 통해 하나씩 조회하는 방식임.
*/
String username = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("username: "+username+" / age: "+age);
/*
* 이름일 동일한 파라미터가 여러 개인 경우 request.getParameterValues()를 활용
*/
String[] usernames = request.getParameterValues("username");
for(String name : usernames) {
System.out.println("username: "+name);
}
}
}
- request.getParameterNames()를 사용하면 가져온 모든 파라미터의 키 값을 가져올 수 있다.
- 키값을 통해 값을 조회할 때는 request.getParameter()를 사용한다.
- 만약 이름이 동일한 키가 여러 개라면 request.getParameterValues()를 사용한다. 만약 이런 상황에서 request.getParameter()를 사용하면 request.getParameterValues()의 첫 번째 값을 반환한다.
5. POST HTML Form
HTML Form을 사용하는 방식을 살펴보자. 해당 방식은 회원 가입, 상품 주문 등에서 주로 사용한다. 이 방식은 메시지 바디에 데이터가 들어가기 때문에 content-type이 있다. 우리의 경우 "application/x-www-form-urlencoded"다. 테스트를 위해서는 일단 아래와 같이 데이터를 전달할 수 있는 html 형식을 만들어야 한다.
위와 같이 값을 전달하면 이전과 동일하게 request.getParameter() 등 Get 쿼리 파라미터에서 살펴본 방식과 동일하게 데이터 조회가 가능하다. 위처럼 HTML Form을 직접 생성하는 방식 말고도 Postman을 통해서 테스트할 수 있다.
- 이와 같이 HTML Form을 통해 데이터를 전송하는 형식(content-type)을 "application/x-www-form-urlencoded"라 한다.
6. API 메시지 바디 (텍스트, JSON)
HTTP든 Rest API든 API 기반의 방식은 API 메시지 바디 방식을 사용한다. HTTP 요청 데이터의 메시지 바디에 내가 원하는 데이터를 직접 실어서 서버에 전송하고, 서버는 이를 읽는다. 가장 먼저, 단순한 텍스트를 전송해보자.
- JSON, XML, TEXT 든 다양한 형식으로 데이터를 보낼 수 있지만 최근에는 JSON으로 거의 보낸다.
- 보통 POST, PUT, PATCH에 주로 사용한다.
@WebServlet(name = "APIRequestString", urlPatterns = "/apiRequestString")
public class APIRequestString extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// request.getInputStream()을 사용하면 body의 내용을 byte code로 바로 얻을 수 있다.
ServletInputStream inputStream = request.getInputStream();
// 위 바이트 코드를 스트링으로 바꾸려면 StreamUtils.copyToString()을 사용하면 된다. 이때 인코딩 정보를 알려줘야 한다.
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
System.out.println("messageBody: "+messageBody);
}
}
이후 아래와 같이 포스트 맨을 통해 텍스트를 보내보자.
그럼 결과는 아래와 같다.
이번에는 JSON 형식으로 데이터를 전달해보자. 이 경우 content-type이 "application/json"이 된다. 일단 json 형식이기 때문에 json 형식의 데이터를 객체로 바꿀 수 있도록 아래와 같이 클래스를 하나 만들자.
@Getter
@Setter
public class UserData {
private String username;
private int age;
}
JSON은 아래와 같이 위에서 만든 클래스의 객체로 파싱할 수 있다. 이때 스프링에서 기본으로 제공하는 jackson 라이브러리의 ObjectMapper를 활용한다.
@WebServlet(name = "APIRequestJson", urlPatterns = "/apiRequestJson")
public class APIRequestJson extends HttpServlet{
// 파싱을 위해 스프링에서 제공하는 jackson 라이브러리를 활용한다.
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. json 형식의 바이트 코드를 받아와서 문자열로 바꿔준다.
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
System.out.println(messageBody);
// 2. UserData 객체로 파싱한다.
UserData userData = objectMapper.readValue(messageBody, UserData.class);
System.out.println("userName: "+userData.getUsername());
System.out.println("age"+userData.getAge());
}
}
7. HttpServletResponse 사용법
이전까지는 HTTP 스펙에서 요청이 오는 것을 어떻게 처리할지 알아봤다. 이번 시간부터는 HttpServletResponse 즉, 응답에 대해 살펴보자. HttpServletResponse는 사실 HTTP 응답 메시지를 생성하는 역할을 한다. 우리가 직접 HTTP 응답 메시지를 만드는 것은 번거롭기 때문에 여러 메서드를 통해 필요한 값들을 넣으면 HttpServletResponse가 HTTP 응답 메시지를 만들 때 사용하게 된다. 그래서 대표적으로 HTTP 응답 코드를 지정할 수 있다. 200, 400, 401, 404 등등을 말한다. 그리고 헤더와 바디 등의 내용을 생성할 수 있다. 또한 ContentType과 같은 헤더를 편리하게 지정하는 기능, 쿠키와 관련하여 편리하게 생성하는 방법 등의 편의 기능을 제공한다. 또한 Redirect도 지원한다. 아래는 HttpServletResponse의 활용 예시 코드다.
@WebServlet(name = "responseHeaderServlet", urlPatterns = "/responseHeader")
public class ResponseHeaderServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// status-line을 말함 (Http 스펙에서 응답의 첫번째 라인)
response.setStatus(HttpServletResponse.SC_OK);
// 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"); // 내가 원하는 헤더도 새로 만들 수 있다.
// 편의 메서드
content(response);
cookie(response);
// message body
PrintWriter writer = response.getWriter();
writer.println("I'm Message Body");
}
private void content(HttpServletResponse response) {
// 위에서 살펴봤던 setHeader로 content type을 지정하는 방식을 아래와 같이 수정할 수도 있다.
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
// Content-Length를 임의로 정할 수도 있고, 생략시에는 자동으로 생성됨.
response.setContentLength(2);
}
private void cookie(HttpServletResponse response) {
/*
* 쿠키를 다음과 같이 선언하고 싶다고 하자.
* Set-Cookie: myCookie=good; Max-Age=600; (해당 쿠키는 600초 동안 유효함.)
* 이는 아래와 같이 세팅하면 된다.
* response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
*/
// 위와 같이 선언하는 것은 귀찮으므로 아래와 같이 선언할 수도 있다.
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600);
response.addCookie(cookie);
}
private void redirect(HttpServletResponse response) throws IOException {
// Status code: 302
// location: /basic/hello-form.html
// response.setStatus(HttpServletResponse.SC_FOUND);
// response.setHeader("Location", "/basic/hello-form.html");
// 하지만 위 방법은 너무 복잡함. 따라서 아래 방식을 사용함.
response.sendRedirect("/basic/hello-form.html");
}
}
8. HTTP 응답 데이터 (텍스트, HTML, API JSON)
이번에는 응답 데이터 부분을 자세히 알아보자. 응답 데이터도 크게 세 가지로 나뉜다.
- 텍스트 → writer.println("ok"); 사용
- HTML 응답
- HTML API (JSON 등)
먼저 HTML로 응답하는 방식을 살펴보자.
@WebServlet(name = "responseHtmlServlet", urlPatterns = "/responseHtml")
public class ResponseHtmlServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. content type을 먼저 잡아줘야 한다. -> text/html; charset=utf-8
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
// 2. writer를 통해 html 내용을 작성해주면 된다.
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println("<div>HI?<div>");
writer.println("</body>");
writer.println("</html>");
}
}
위와 같이 Content-Type을 올바르게 설정해주고 writer를 통해 html을 작성해주면 된다. 다음으로 JSON으로 응답을 주는 방식을 살펴보자.
@WebServlet(name = "responseJsonServlet", urlPatterns = "/responseJson")
public class ResponseJsonServlet extends HttpServlet{
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. Content-Type: application/json으로 설정한다.
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
// 2. JSON으로 전달할 객체를 생성해준다.
UserData userData = new UserData();
userData.setUsername("nam");
userData.setAge(20);
// 3. 위 객체를 JSON으로 형태를 바꿔야한다. {"username":"nam", "age":20}
String result = objectMapper.writeValueAsString(userData);
response.getWriter().write(result);
}
}
이전과 동일하게 Content-Type 을 "application/json"으로 설정하고, json으로 전달할 객체 정보를 생성한 다음, ObjectMapper 객체를 통해 스트링으로 변환하여 writer로 response에 바디를 작성하면 된다.
출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
'BackEnd > Spring' 카테고리의 다른 글
[Spring MVC-1] MVC 프레임워크 만들기 (0) | 2023.09.19 |
---|---|
[Spring MVC-1] 서블릿, JSP, MVC 패턴 (0) | 2023.09.12 |
[Spring MVC-1] 웹 어플리케이션 이해 (0) | 2023.09.06 |
[Spring] 빈 스코프 (0) | 2023.09.02 |
[Spring] 빈 생명주기 콜백 (0) | 2023.08.31 |