본 포스팅은 인프런 - 스프링 MVC 1편을 강의를 바탕으로 공부하고 정리한 글입니다.
📢 본 포스팅에 앞서 예제를 위한 프로젝트를 생성하자.
📌 스프링 프로젝트 생성
스프링 부트 스타터를 이용해서 스프링 프로젝트를 생성해주도록 하자.
- 프로젝트 선택
- Project: Gradle
- Project Language: Java
- Spring Boot: 2.6.x (정식버전 중 가장 최신 버전 선택)
- Project Metadata
- Group: hello
- Artifact: servlet
- Name: servlet
- Package name: hello.servlet
- Packaging: War (JSP를 실행하기 위해 선택)
- Java: 11
- Dependencies
- Spring Web
- Lombok
📌 실행 확인
인텔리제이로 프로젝트를 Open하고, 동작하는지 확인한다.
- 기본 메인 클래스 실행 (ServletApplication.main())
- http://localhost:8080 호출해서 Whitelabel Error Page가 나오면 정상 동작
📌 자바로 실행하기
최근 인텔리제이 버전은 Gradle을 통해 실행하는 것이 기본값인데, 이렇게 하면 실행속도가 느리기 때문에 자바로 바로 실행하도록 설정을 변경해준다.
- 윈도우 사용자 : File → Setting → Gradle 검색
- 맥 사용자 : Preferences → Gradle 검색
- Build and run using : Gradle → IntelliJ IDEA 변경
- Run tests using : Gradle → IntelliJ IDEA
인텔리제이 무료 버전의 경우 War 파일의 톰캣이 정상 시작되지 않는 문제가 발생할 수 있어 해당 설정을 IntelliJ IDEA가 아닌 Gradle로 설정해야 한다. (유료버전은 정상 동작)
또는 build.gradle에 있는 다음 코드를 제거해도 된다.
→ providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
📌 롬복 적용
- File → Setting(맥:Preferences) → plugin → lombok 검색 설치 (재시작)
- File → Setting(맥:Preferences) → Annotation Processors 검색 → Enable annotation processing 체크 (재시작)
- 임의의 테스트 클래스를 만들고 @Getter, @Setter 확인
📌 포스트맨 준비
- 포스트맨 설치 : https://www.postman.com/downloads
서블릿 적용
스프링 부트 환경에서 서블릿을 등록하고 사용해보자.
📁 ServletApplication
@ServletComponentScan
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
- @ServletCompoenentScan : 서블릿 자동 등록 어노테이션
- 스프링 부트는 서블릿을 직접 등록해서 사용할 수 있도록 @ServletCompoenentScan 어노테이션을 지원한다.
📁 basic/HelloServlet
@WebServlet(name="helloServlet", urlPatterns="/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet.service");
System.out.println("request = " + request);
System.out.println("response = " + response);
// 요청 받기 (request)
String username = request.getParameter("username");
System.out.println("username = " + username);
// 응답 보내기 (response)
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().write("hello " + username);
}
}
- @WebServlet : 서블릿 어노테이션
- name : 서블릿 이름
- urlPatterns : URL 매핑
- HTTP 요청을 통해 매핑된 URL이 호출되면 서블릿 컨테이너는 service 메서드를 실행한다.
- 웹 브라우저 실행 URL : http://lacalhost:8080/hello?username=lim
- 웹 브라우저 결과 : hello lim
- 콘솔 결과
❗️ HTTP 요청 메세지를 로그로 확인하기
다음 설정을 추가하면 서버가 받은 HTTP 요청 메세지를 로그에 출력할 수 있다.
📁 resource/application.porperties
logging.level.org.apache.coyote.http11=debug
// 로그
...o.a.coyote.http11.Http11InputBuffer: Received [GET /hello?username=servlet
HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/88.0.4324.150 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.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/basic.html
Accept-Encoding: gzip, deflate, br
Accept-Language: ko,en-US;q=0.9,en;q=0.8,ko-KR;q=0.7
]
이 출력을 통해 개발 단계에서 요청이 잘 들어오는지 확인할 수 있다. (운영서버에 모든 요청 정보를 다 남기면 성능저하가 발생할 수 있기 때문에 개발 단계에서만 사용 권장)
💡 서블릿 컨테이너 동작 방식
- 스프링 부트를 실행하면 내장 톰켓 서버를 띄운다.
- 톰켓 서버는 내부에 서블릿 컨테이너 기능을 가지고 있으며, 서블릿 컨테이너가 서블릿 객체를 생성한다.
- HTTP 요청 메세지를 받으면 request, response 객체를 만들어 서블릿(helloServlet)을 호출해준다.
- respose 정보로 HTTP 응답 메세지를 만들어 웹 브라우저로 보내며, 웹 브라우저는 응답 메세지를 통해 화면을 띄워준다.
welcom 페이지 추가
예제를 위한 welcom페이지인 index.html과 basic.html를 만들어보자.
📁 webapp/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li><a href="basic.html">서블릿 basic</a></li>
</ul>
</body>
</html>
📁 basic.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>hello 서블릿
<ul>
<li><a href="/hello?username=servlet">hello 서블릿 호출</a></li>
</ul>
</li>
<li>HttpServletRequest
<ul>
<li><a href="/request-header">기본 사용법, Header 조회</a></li>
<li>HTTP 요청 메시지 바디 조회
<ul>
<li><a href="/request-param?username=hello&age=20">GET -
쿼리 파라미터</a></li>
<li><a href="/basic/hello-form.html">POST - HTML Form</a></
li>
<li>HTTP API - MessageBody -> Postman 테스트</li>
</ul>
</li>
</ul>
</li>
<li>HttpServletResponse
<ul>
<li><a href="/response-header">기본 사용법, Header 조회</a></li>
<li>HTTP 응답 메시지 바디 조회
<ul>
<li><a href="/response-html">HTML 응답</a></li>
<li><a href="/response-json">HTTP API JSON 응답</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
HttpServletRequest
- 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신 HTTP 요청 메시지를 파싱한다.
- 파싱한 결과를 HttpServletRequest 객체에 담아서 제공한다.
- 따라서 HttpServletRequest 객체를 사용해 HTTP 요청 메시지를 편리하게 조회할 수 있다.
- HttpServletRequest 객체의 부가기능
- 임시 저장소 기능을 제공 (해당 HTTP 요청 시작부터 끝날 때까지 유지)
- 저장 : request.setAttribute(name, value)
- 조회 : request.getAttribute(name)
- 세션 관리 기능을 제공
- request.getSession(create:ture)
- 임시 저장소 기능을 제공 (해당 HTTP 요청 시작부터 끝날 때까지 유지)
HTTP 요청 메시지 조회
실제 코드를 통해 HttpServletRequest를 사용해 HTTP 메시지의 시작 라인, 헤더 정보를 조회해보자.
📁 basic/request/RequestHeaderServlet
// http://localhost:8080/request-header
@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); // 기타 정보 조회
}
}
👉🏻 시작 라인 정보 조회
private void printStartLine(HttpServletRequest request) {
System.out.println("--- REQUEST-LINE - start ---");
System.out.println("request.getMethod() = " + request.getMethod()); // GET
System.out.println("request.getProtocal() = " + 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-test
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();
}
👉🏻 헤더 정보 조회
private void printHeaders(HttpServletRequest request) {
System.out.println("--- Headers - start ---");
/* 헤더 조회 방법1
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
*/
/* 헤더 조회 방법2 */
request.getHeaderNames().asIterator()
.forEachRemaining(headerName -> System.out.println(headerName + ": " + request.getHeader(headerName)));
System.out.println("--- Headers - end ---");
System.out.println();
}
👉🏻 헤더 편리한 조회
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();
}
👉🏻 기타 정보 조회
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가지 방법을 사용해 데이터를 전달한다.
- 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에서 주로 사용하는 방식이다.
- JSON, XML, TEXT 정보를 그대로 담아 전달한다. (요즘에는 주로 JSON을 사용)
- POST, PUT, PATCH을 사용할 수 있다.
GET - 쿼리 파라미터
HTTP 요청 데이터 중 GET 방식의 쿼리 파라미터로 전달되는 데이터를 어떻게 사용할 수 있는지 알아보자.
전달 데이터가 다음과 같을 때,
- username = hello
- age = 20
메시지 바디 없이, URL에 쿼리 파라미터 형식으로 데이터를 전달한다.
- url?username=hello&age=20
- ?로 쿼리 파라미터를 시작하고, 추가 파라미터는 &로 구분한다.
그럼 서버에서는 HttpServletRequest가 제공하는 메소드를 통해 받은 쿼리 파라미터를 조회할 수 있다.
// 전체 파라미터 조회
Enumeration<String> parameterNames = request.getParameterNames();
// 파라미터를 Map으로 조회
Map<String, String[]> parameterMap = request.getParameterMap();
// 단일 파라미터 조회
String username = request.getParameter("username");
// 복수 파라미터 조회
String[] usernames = request.getParameterValues("username");
- 단일 파라미터일 경우 getParameter() 메소드 사용
- 복수 파라미터일 경우 getParameterValue() 메소드 사용
👉🏻 예제 코드
/**
* Get 방식의 쿼리 파라미터 전송
* http://lacalhost:8080/request-param?username=hello&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");
String age = request.getParameter("age");
System.out.println("username = " + username);
System.out.println("age = " + age);
System.out.println();
// 이름이 같은 복수 파라미터 조회
// http://lacalhost:8080/request-param?username=hello&username=hello2
System.out.println("[이름이 같은 복수 파라미터 조회]");
String[] usernames = request.getParameterValues("username");
for (String name : usernames) {
System.out.println("name = " + name);
}
response.getWriter().write("ok");
}
}
POST - HTML Form
HTTP 요청 데이터 중 POST 방식의 HTML Form으로 전달되는 데이터를 어떻게 사용할 수 있는지 알아보자.
이 방식은 다음과 같은 특징을 가진다.
- content-type : application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달
Post 요청을 위한 간단한 HTML Form을 하나 생성하자.
👉🏻 HTML Form 생성
📁 webapp/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>
만들어준 HTML Form에 데이터를 적어 전송하면 웹 브라우저는 다음 형식으로 HTTP 요청 메시지를 만든다.
- 요청 URL : http://localhost:8080/request-param
- content-type : application/x-www-form-urlencoded
- message body : username=hello&age=20
이 형식은 앞서 GET에서 살펴본 쿼리 파라미터 형식과 같다.
따라서 쿼리 파라미터 조회 메소드를 그대로 사용할 수 있다.
클라이언트(웹 브라우저) 입장에서는 데이터를 전송하는 방식에 차이가 있지만, 서버 입장에서는 둘의 형식이 쿼리 파라미터로 동일하기 때문에 getParameter() 메소드로 조회가 가능하다!
content-type은 HTTP 메시지 바디의 데이터 형식을 지정한다.
GET URL 쿼리 파라미터 형식으로 데이터를 전달할 경우에는 HTTP 메시지 바디를 사용하지 않기 때문에 content-type이 없다.
Post HTML Form 형식으로 데이터를 전달할 경우에는 HTTP 메시지 바디에 데이터를 포함해서 보내기 때문에 바디에 포함된 데이터가 어떤 형식인지 content-type을 반드시 지정해줘야 한다.
이렇게 폼으로 데이터를 전송하는 형식을 application/x-www-form-urlencoded라 한다.
👉🏻 Postman 테스트
이때 위와 같이 간단하게 username, age 데이터를 폼으로 전송하는 간단한 테스트에 HTML Form을 만들기 귀찮을 수 있다.
이때 Postman을 사용하면 Form을 만들지 않고도 테스트를 진행할 수 있다.
- POST 선택
- Body → x-www-form-urlencoded 선택
- Headers에서 content-type : application/x-www-form-urlcoded로 지정된 부분 확인하기
API 메시지 바디 - TEXT
HTTP 요청 데이터 중 HTTP 메시지 바디에 데이터를 직접 담아 전달하는 방식을 알아보도록 하자.
이 방식의 특징은 다음과 같다.
- HTTP API에서 주로 사용
- 데이터 형식 : JSON, XML, TEXT (주로 JSON을 사용)
- POST, PUT, PATCH 사용이 가능하다.
우선 가장 단순한 텍스트 메시지를 담아 전달하고 조회해보자.
📁 basic/request/RequestBodyStringServlet
@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(); // 바이트 코드로 반환해줌
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);// 바이트 코드 -> 문자로 변환할 때는 인코딩 정보(UTF_8)를 반드시 지정해야함
System.out.println("messageBody = " + messageBody);
response.getWriter().write("ok");
}
}
- getInputStream() 메소드를 통해 HTTP 메시지 바디의 데이터를 직접 읽을 수 있다.
👉🏻 포스트맨 테스트
TEXT 형식의 전송은 다음과 같이 이뤄진다.
- POST http://localhost:8080/request-body-string
- content-type : text/plain
- message body : hello!
- 결과
messageBody = hello!
API 메시지 바디 - JSON
이번에는 단순 텍스트가 아닌 JSON 형식으로 데이터 전달하는 방법을 알아보자.
JSON 형식의 데이터는 그대로 사용하지 않고 객체로 바꿔서 사용한다.
따라서 JSON 형식으로 파싱할 수 있도록 객체를 하나 생성해줘야 한다.
👉🏻 HelloData 객체 생성
📁 basic/HelloData
@Getter // 롬복 사용
@Setter // 롬복 사용
public class HelloData{
private String username;
private int age;
}
📁 basic/request/RequestBodyJsonServlet
/**
* JSON 형식 전송
* http://localhost:8080/request-body-json
* content-type : application/json
* message body : {"username" : "hello", "age" : 20}
*/
@WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper(); // JSON 변환 라이브러리인 Jackson 라이브러리(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);
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 결과를 파싱해서 자바 객체로 변환하기 위해서는 JSON 변환 라이브러리를 추가해서 사용해야 한다.
스프링 부트로 SpringMVC를 선택하면 기본으로 Jackson 라이브러리(ObjectMapper)를 함께 제공해준다.
👉🏻 포스트맨 테스트
JSON 형식의 전송은 다음과 같이 이뤄진다.
- POST http://localhost:8080/request-body-json
- content-type : application/json
- message body : {"username" : "hello", "age" : "20"}
- 결과
messageBody = {"username":"hello", "age":20}
helloData.getUsername() = hello
helloData.getAge() = 20
HttpServletResponse
- HTTP 응답 메시지 생성해준다.
- HTTP 응답코드 지정할 수 있다.
- 헤더와 바디를 생성할 수 있다.
- HttpServletResponse의 편의 기능
- Content-Type
- 쿠키
- Redirect
실제 코드를 통해 HttpServletResponse의 사용 방법을 알아보자.
📁 basic/response/ResponseHeaderServlet
/**
* http://localhost:8080/response-header
*/
@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 응답코드
response.setStatus(HttpServletResponse.SC_OK); // 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");
}
}
@WebServlet (name = "ResponseHeaderServlet", urlPatterns = "/response-header")
public class ResponseHeaderServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
// [header 편의 메소드]
// content(response); // content-type
cookie(response); // cookie
redirect(response); // redirect
// [message body]
PrintWriter writer = response.getWriter();
writer.println("ok");
}
}
👉🏻 Content 편의 메소드
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");
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600); //600초
response.addCookie(cookie);
}
👉🏻 redirect 편의 메소드
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 응답 데이터 보내기
HTTP 응답 메시지는 주로 다음 내용을 담아서 전달한다.
- 단순 텍스트 응답 → 예) writer.println("ok");
- HTML 응답
- HTTP API - message body JSON 응답
HTML 응답
📁 basic/response/ResponseHtmlServlet
/**
* http://localhost:8080/response-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");
// HTML
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>안녕?</div>");
writer.println("</body>");
writer.println("</html>");
}
}
- HTTP 응답 데이터로 HTML을 반환할 경우 content-type을 text/html로 지정해줘야 한다.
- 결과
API 응답 - JSON
📁 basic/response/ResponseJsonServlet
/**
* http://localhost:8080/response-json
*/
@WebServlet (name = "ResponseJsonServlet", urlPatterns = "/response-json")
public class ResponseJsonServlet extends HelloServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@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 = new HelloData();
helloData.setUsername("lim");
helloData.setAge(20);
// {"username":"lim", "age":20}
String result = objectMapper.writeValueAsString(helloData);
response.getWriter().write(result);
}
}
- HTTP 응답 데이터로 JSON을 반환할 경우 content-type을 application/json으로 지정해줘야 한다.
- Jackson 라이브러리가 제공하는 objectMapper.writeValueAsString() 메소드를 사용하면 객체를 JSON 문자로 변경할 수 있다.
- 결과
'🌱 Spring > Web MVC' 카테고리의 다른 글
스프링 MVC 웹 페이지 만들기 (0) | 2022.03.22 |
---|---|
로깅 (0) | 2022.03.18 |
스프링 MVC 기본 기능 (0) | 2022.03.18 |
스프링 MVC 구조 이해하기 (0) | 2022.03.17 |
MVC 프레임워크 만들기 (0) | 2022.03.16 |
서블릿, JSP, MVC 패턴으로 웹 애플리케이션 개발하기 (0) | 2022.03.15 |
자바 웹 기술의 역사 (2) | 2022.03.11 |
웹 애플리케이션의 이해 (0) | 2022.03.11 |