이 글은 김영한 강사님의 강의를 참고하여 작성하였습니다.
@SpringBootApplication
에서 @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("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 = "/경로")
- 서블릿 등록
-> urlPatterns: HTTP 요청에 매핑된 url임
-> 해당 url이 호출되면 서블릿의service()
실행됨
http://localhost:8080/hello?username=world
가 호출되면...
- HTTP 요청 메시지를 '기반'으로
request와 response 객체
를 생성- service() 메소드를 호출하여 싱글톤 객체 'helloServlet'에서 값을 세팅
- 서블릿이 종료된 상태에서 우리가 값을 세팅한 response 객체를 불러와 'HTTP 응답'을 생성해서 보내줌.
application.properties에서
logging.level.org.apache.coyote.http11=debug
으로 세팅해주고 다시 서버 시작!
request.setAttribute(name, value)
request.getAttribute(name)
request.getSession(create: true)
//start line 정보
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();
}
//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("[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();
}
http://localhost:8080/request-param?username=hello&age=20
단일 파라미터 조회
String username = **request.getParameter("username")**;
파라미터 이름들 모두 조회
Enumeration<String> parameterNames = request.getParameterNames();
파라미터를 Map으로 조회
Map<String, String[]> parameterMap = request.getParameterMap();
복수 파라미터 조회
String[] usernames = request.getParameterValues("username");
if) 중복이고 모든 값을 내보내고 싶다면
request.getParameterValues("username")
if) 그냥 맨 앞에 값 하나만 내보내고 싶다.
request.getParameter()
=> 단일 조회 메소드 이기 때문
: application/x-www-form-urlencoded
http://localhost:8080/request-param
application/x-www-form-urlencoded
username=hello&age=20
request.getParameter()
은 2가지 모두(GET URL 쿼리 파라미터 형식,POST HTML Form
형식 )를 지원한다.
* content type은 HTTP 메시지 바디의 '데이터 형식'을 지정하는 곳
- POST HTML FORM 형식은 '메시지 바디' 부분에 데이터를 포함해 보낸다.
=> GET url 쿼리 파라미터와 달리 얘는 반드시 '어떤 데이터 형식을 쓰는지' 지정이 필요
• 'HTTP message body'에 데이터를 직접 담아서 요청
• HTTP API에서 주로 사용, JSON, XML, TEXT
• 데이터 형식은 주로 JSON 사용
* [POST, PUT, PATCH]
• 문자 전송
• [POST] http://localhost:8080/request-body-string
• content-type: text/plain
• message body: hello
• 결과: messageBody = hello
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream,
StandardCharsets.UTF_8);
request.getInputStream()
: request의 '메시지 바디'의 내용을 byte 타입으로 가져온다.String messageBody = StreamUtils.copyToString(inputStream,StandardCharsets.UTF_8);
은 앞의 byte타입으로 가져온 '메시지 바디'내용을 문자열 중 'UTF-8'로 가져오겠다는 뜻.
• 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-bodyjson")
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");
}
}
- content-type: application/json (Body raw, 가장 오른쪽에서 JSON 선택
- message body: {"username": "hello", "age": 20} 입력
- 스프링 부트를 선택시 '기본'으로 'Jackson' 라이브러리를 함꼐 제공함
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);
}
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");
}
redirect 경로를 제시해줌.
1) 단순 텍스트 응답
- 앞에서 살펴봄 ( writer.println("ok"); )
2) HTML 응답
3) HTTP API - MessageBody JSON 응답
@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로 응답하기 때문에
content-type : text/html
로 지정
@WebServlet(name = "responseJsonServlet", urlPatterns = "/response-json")
public class ResponseJsonServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
//Content-Type: application/json
response.setHeader("content-type", "application/json");
response.setCharacterEncoding("utf-8");
HelloData data = new HelloData();
data.setUsername("kim");
data.setAge(20);
//{"username":"kim","age":20}
String result = objectMapper.writeValueAsString(data);
response.getWriter().write(result);
}
}
- JSON을 반환할 때는 content-type을
application/json
로 지정objectMapper.writeValueAsString()
: '객체'를 JSON 문자로 변경할 수 있다.
application/json
은 기본 스펙상 utf-8 형식을 사용함 charset=utf-8
쓰는거 무의미application/json;charset=utf-8
(x)response.getWriter()
를 사용 하면 위와 같은 일이 생김response.getOutputStream()
를 쓰자