서블릿 사용 & 등록
서블릿 사용
@ServletComponentScan
: Springboot환경에서 서블릿을 등록할수 있도록 지원하는 어노테이션
@ServletComponentScan //서블릿을 사용하겠다는 선언
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
서블릿 등록 과정
@WebServlet
: 서블릿의 이름과 연결 url을 지정시켜주는 어노테이션HttpServlet
클래스 상속- protected 접근 지정자인
service()
메서드를 Override → 서블릿 컨테이너는 HTTP 요청을 통해 매핑된 URL이 호출되면 service 메서드를 실행한다. - service메서드에 로직을 작성
@WebServlet(name = "helloServlet", urlPatterns = "/hello") //1. 서블릿 이름과 url 지정
public class HelloServlet extends HttpServlet { //2. HttpServlet 상속
//3. service 메서드 Override
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//4. 해당 url이 호출되면 실행할 비즈니스 로직 작성
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);
}
}
HttpServletRequest
- HTTP request 메시지를 파싱해서 편리하게 사용하도록 제공되는 객체
정보 조회 기능
- start line 조회 : HTTP메소드, URL, 쿼리 스트링, 스키마, 프로토콜
- 헤더 조회
- 바디 조회 : form 파라미터, message body데이터 직접 조회
부가 기능
- 임시 저장소 기능 : 해당 HTTP요청이 시작부터 끝날 떄 까지 유지되는 임시저장소
- 저장 :
req.setAttribute(name, value)
- 조회 :
req.getAttribute(name)
- 저장 :
- 세션 관리 기능
request.getSession(create: true)
정보 조회 제공 메서드
- start line 조회 메서드 : HTTP메소드, URL, 쿼리 스트링, 스키마, 프로토콜
- 헤더 조회 메서드 : Host, Language, cookie, Content
- 기타 정보 조회
HTTP 요청 데이터
클라이언트에서 서버로 가는 데이터를 요청 하는 클래스
1. GET - 쿼리 파라미터
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 주로 검색, 필터, 페이징등에서 많이 사용하는 방식
- EX) /url?username=hello&age=20
// 파라미터 전송 기능
// 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("[전체 파라미터 조회] - 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("[이름이 같은 복수 파라미터 조회]");
String[] usernames = request.getParameterValues("username");
for (String name : usernames) {
System.out.println("name = " + name);
}
response.getWriter().write("ok");
}
}
2. POST - HTML Form
- HTML의 Form형식에서 데이터를 전달
- 데이터의 형식은 쿼리 파라미터와 동일하므로 같은 방법으로 조회 가능
- Content-Type 지정 :
application/x-www-form-urlencoded
반드시 지정해야함!
→ HTTP 메시지 바디에 해당 데이터를 포함해서 보내기 때문에 바디에 포함된 데이터가 어떤 형식인지 content-type을 꼭 지정해야 한다.
3. HTTP request message의 body
- content-type: application/json
요청한 데이터가 단순 Text인 경우
@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(); //ServletInputStream객체로 데이터를 받음
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
//byte코드 형태를 String형태로 변환, Charset을 UFT-8로 지정
System.out.println("messageBody = " + messageBody);
response.getWriter().write("ok");
}
}
- byte 코드를 String 형태로 변환 해야 한다.
- Charset을 지정해야 한다 → UTF_8
요청한 데이터가 JSON형태인 경우
- message body: {"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);
//Jackson라이브러리의 ObjectMapper 클래스를 사용해서 변환
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
System.out.println("helloData.getUsername = " + helloData.getUsername());
System.out.println("helloData.getAge = " + helloData.getAge());
}
}
- text형태와 같이 데이터를 받아서 String형으로 변환
- String형태를 사용하기 좋게 객체로 바꾼다 → Springboot에서 기본 제공되는 Jackson라이브러리의 ObjectMapper 클래스 이용
HttpServletResponse
- 서버에서 클라이언트로 가는 데이터를 조회하는 클래스
- HTTP 응답 메시지 생성 : HTTP 응답코드 지정, 헤더생성, 바디 생성
- 편의기능 제공 : Content-Type, 쿠키, Redirect
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);
//응답코드 200 보다 이렇게 정의된 값(SC_OK)으로 쓰는게 보기에 좋다.
//[response-headers]
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");
//데이터 타입 등등 지정
//[Header 편의 메서드]
content(response);
cookie(response);
redirect(response);
//setHeader 메서드와 달리 각각의 메서드로 지정
//[message body]
PrintWriter writer = response.getWriter();
writer.println("ok");
}
setStatus()
: 응답코드를 지정setHeader()
: 텍스트로 header의 정보를 지정해줄수 있다.- Header편의 메서드 :
content()
,cookie()
,redirect()
등
Content, cookie, redirect 편의제공 메서드
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"); //다음 Http요청시 자동 cookie 포함
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"); //302코드 일경우 해당 html로 이동
}
반응형