Hello 서블릿
프로젝트를 생성한뒤 코드를 작성해 보자.
먼저 spring boot에서 servlet을 사용하려면
@ServletComponentScan
를 통해 자동으로 servlet을 등록해준다.
hello.servlet.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");
}
}
이때 ctrl+o를 통해 메서드를 자동으로 만들수 있다.
잘 실행이 된다.
@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);
String username = request.getParameter("username");
System.out.println("username = " + username);
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().write("hello " + username);
}
}
- @WebServlet 서블릿 애노테이션
- name: 서블릿 이름
- urlPatterns: URL 매핑
application.properties에 logging.level.org.apache.coyote.http11=debug를 추가해주면
서버가 받은 HTTP 요청 메시지를 출력하는것을 확인할 수 있다.
welcome page 만들기
main.webapp에 index.html을 만들면 localhost:8080을 호출하면 index.html 페이지가 열린다.
HttpServletRequest - 개요
서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다.
해당 결과를 HttpServletRequest 객체에 담아서 제공한다.
HttpServletRequest - 기본 사용법
hello.servlet.basic.request에 RequestHeaderServlet 클래스를 만들자.
@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);
}
}
start-line 정보, 헤더 정보,Header 편리한 조회, 기타정보 조회가 가능하다.
HTTP 요청 데이터 - 개요
- GET - 쿼리 파라미터
- /url?username=kim&age=20
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 예) 검색, 필터, 페이징등에서 많이 사용하는 방식
- POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파리미터 형식으로 전달 username=kim&age=20
- 예) 회원 가입, 상품 주문, HTML Form 사용
- HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
HTTP 요청 데이터 - GET 쿼리 파라미터
username=hello와 age=20을 전달한다고 하면
http://localhost:8080/request-param?username=hello&age=20 다음과 같이 전달하면된다.
?로 시작을 하고 &로 추가 파라미터를 구분한다.
/**
* 1. 파라미터 전송
* http://localhost: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("[단일 파라미터 조회] - start");
String username = request.getParameter("username");
String age = request.getParameter("age");
System.out.println("username = " + username);
System.out.println("age = " + age);
System.out.println("[이름이 같은 복수 파라미터 조회]");
String[] usernames = request.getParameterValues("username");
for (String name : usernames) {
System.out.println("username=" + name);
}
response.getWriter().write("ok");
}
}
각각의 방법으로 전체 파라미터 조회, 단일 파라미터 조회, 중복되는 복수의 파라미터를 조회 할 수 있다.
HTTP 요청 데이터 - POST HTML Form
content-type은 다음과 같다
application/x-www-form-urlencoded
get방식과 같이 쿼리 파라미터 방식으로 전달한다. ex) username=hello&age=20
<form action="/request-param" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
위와 같이 입력창을 만든다. 해당 form은 action이 /request-param으로 넘어가고
전체 파라미터 조회, 단일 파라미터 조회, 중복되는 복수의 파라미터가 출력된다.
결과적으로 POST 방식은 GET 방식의 쿼리 파라미터 방법과 같은 형식으로 전송이된다.
POST 방식은 content-type은 application/x-www-form-urlencoded 이고, message body는 username=hello&age=20 이다.
반면에 GET 쿼리 파라미터 방식은 HTTP 메시지 바디를 사용하지 않기 때문에 content-type이 없다.
형식이 똑같기 때문에 request.getparameter를 통해 둘다(get,post) 꺼낼수 있다.
HTTP 요청 데이터 - API 메시지 바디 - 단순 텍스트
HTTP message body에 데이터를 직접 담아서 요청
POST http://localhost:8080/request-body-string
content-type: text/plain
message body: hello
결과: messageBody = hello
@WebServlet(name = "eequestBodyStringServlet",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);
System.out.println("messageBody = " + messageBody);
response.getWriter().write("ok");
}
}
postman을 이용해서 text전송을 해보자
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}
@WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {
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);
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 )를 함께 제공한다.
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]
response.setStatus(HttpServletResponse.SC_OK);
//[response-header]
response.setHeader("Content-Type", "text/plain;charset=utf-8");
response.setHeader("Cache-Control", "no-cache, no-store, mustrevalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("my-header","hello");
PrintWriter writer = response.getWriter();
writer.println("ok");
}
}
setHeader를 통해 응답코드(HttpServletResponse.SC_OK)와 응답헤더(Content-Type 등등)를 설정 할 수 있다.
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
SC_BAD_REQUEST를 사용하면 아래와 같이 상태코드가 400이 된다.
response.setHeader("Content-Type", "text/plain;charset=utf-8");
위에서 사용한 해당 코드는 아래의 코드로 변경 할 수 있다.
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
cookie도 setHeader 함수를 통해 설정 할 수 있지만, cookie 객체를 통해 더 쉽게 설정 할 수 있다.
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600); //600초
response.addCookie(cookie);
HttpServletResponse - HTML 응답
HTTP 응답으로 HTML을 반환할 때는 content-type을 text/html 로 지정해야 한다.
//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>");
HTTP 응답 데이터 - API JSON
HTTP 응답으로 JSON을 반환할 때는 content-type을 application/json 로 지정해야 한다
//Content-Type: application/json
response.setHeader("content-type", "application/json");
response.setCharacterEncoding("utf-8");
HelloData helloData = new HelloData();
helloData.setUsername("kim");
helloData.setAge(20);
//{"username":"kim","age":20}
String result = objectMapper.writeValueAsString(helloData);
response.getWriter().write(result);
'Java , Spring > Spring' 카테고리의 다른 글
[Spring] @PathVariable, @RequestParam, @ModelAttribute, @RequestBody (0) | 2023.08.21 |
---|---|
[Spring] @Controller 와 @RestController (0) | 2023.08.07 |
초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 - 5장 컴포넌트 스캔, 6장 빈 라이프사이클과 범위 (0) | 2023.05.19 |
초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 - 4장 의존 자동 주입 (0) | 2023.05.19 |
초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 - 2장, 3장 (0) | 2023.05.16 |
댓글