Web Programming/JSP & SERVLET
[JSP & SERVLET] 2.서블릿 프로그래밍
JEONGGI
2021. 6. 9. 03:07
- 서버 프로그램 구현기술
- 서블릿 프로그래밍
- 서블릿 기초
- URL 패턴 매핑 규칙
- 서블릿 동작 과정(Servlet Contaier의 역할)
- 서블릿의 단점 및 JSP 사용 이유
- 서블릿 프로그래밍
- 서블릿을 개발할 수 있다
- 서블릿의 단점과 jsp의 탄생 배경을 이해한다
실습
- tomcat download : http://tomcat.apache.org/
- tomcat start / shutdown
- eclipse tomcat 설정
- BasicServlet
1. 서블릿 기초
WEB-INF (반드시 존재해야한다)
- web.xml : 가장 먼저 어떤식으로 실행되는지에 대해서 설명해 주는곳
- lib : jar파일이 담겨있는 곳
- classes
webapps 폴더 : 각 폴더는 서버에서 구동되는 웹 어플리케이션이다.
서버의 실행 : startup.bat
ROOT : localhost를 대신하는것
=> webapps 폴더 안 war파일이 있을때 서버가 start되면 자동적으로 압축이 풀어지고 실행할 수 있다.
궁극적으로 할 것 : war나 폴더를 webapps에 넣어주는것 => 배포이다.
- eclipse tomcat 설정
1) 서버생성
2) Runtime 설정
- BasicServlet
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 서블릿을 생성하는 방법
// 1. HttpServelt 클래스를 상속한다.
// 2. doXXX 메소드를 구현한다.
// 3. servlet은 정적 자료와 다르게 이름이 없다.
// localhost/ServletTest.index.html 처럼 호출 할 수 없다.
// url - 서블릿 매핑하는 작업이 필요하다.
// url을 직접 이름을 생성해주어야 한다.(web.xml)
public class BasicServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
//resp.setCharacterEncoding("utf-8");
//writer 객체를 통해 html 문서를 생성해준다.
PrintWriter writer = resp.getWriter();
writer.println("<html>");
writer.println(" <head></head>");
writer.println(" <body>현재시간 : "+ new Date() +"</body>");
writer.println("</html>");
writer.flush();
writer.close();
}
}
=> 자바 코드를 이용해서 동적으로 바뀌는 html 코드를 생성하는것이 핵심이다.
=> tomcat이 기동되면(사용자의 요청) sevlet-mapping 을보고서 어떤 서블릿에서 처리할지 tomcat이 실행해주는것
2. 서블릿 사이클
- life cycle : init, destory
- request : service → doXXX
- 생성시 init 처음한번
- 사용자들이 요청을 할때 웹 브라우저에 요청할것이다.
- 요청하는 방법
- 웹 브라우저 주소줄에 주소입력 + enter -> GET
- 버튼 : form - get // form - post
- link를 클릭해서 연결 -> GET
- HTTP Method : 데이터를 주고받는 방식
HTTP 메소드 |
RFC | 요청에 Body가 있음 |
응답에 Body가 있음 |
안전 | 멱등 (Idempotent) |
캐시가능 |
GET | RFC 7231 | 아니오 | 예 | 예 | 예 | 예 |
HEAD | RFC 7231 | 아니오 | 아니오 | 예 | 예 | 예 |
POST | RFC 7231 | 예 | 예 | 아니오 | 아니오 | 예 |
PUT | RFC 7231 | 예 | 예 | 아니오 | 예 | 아니오 |
DELETE | RFC 7231 | 아니오 | 예 | 아니오 | 예 | 아니오 |
CONNECT | RFC 7231 | 예 | 예 | 아니오 | 아니오 | 아니오 |
OPTIONS | RFC 7231 | 선택 사항 | 예 | 예 | 예 | 아니오 |
TRACE | RFC 7231 | 아니오 | 예 | 예 | 예 | 아니오 |
PATCH | RFC 5789 | 예 | 예 | 아니오 | 아니오 | 예 |
- get 방식은 바디가 없다.
- post는 form태그에 내용들을 바디에 숨겨서 가져온다
- get은 URL에 노출이된다
ex) 로그인시 GET방식은 주소줄에 노출이 되기 대문에 POST방식으로 전송한다.
- URL로 식별되는 객체에서 수행 할 메소드
- GET : 단순 요청
- POST : form을 통한 입력 / 저장시
- PUT, DELETE, TRACE 등
서블릿 맵핑에 해당하는 요청이 오게되면 해당 서블릿의 서비스 메소드를 호출하게 된다. service() 를 호출한다.
/**
* Receives standard HTTP requests from the public
* <code>service</code> method and dispatches
* them to the <code>do</code><i>XXX</i> methods defined in
* this class. This method is an HTTP-specific version of the
* {@link javax.servlet.Servlet#service} method. There's no
* need to override this method.
*
* @param req the {@link HttpServletRequest} object that
* contains the request the client made of
* the servlet
*
* @param resp the {@link HttpServletResponse} object that
* contains the response the servlet returns
* to the client
*
* @exception IOException if an input or output error occurs
* while the servlet is handling the
* HTTP request
*
* @exception ServletException if the HTTP request
* cannot be handled
*
* @see javax.servlet.Servlet#service
*/
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod(); // 메소드에서 리턴하는 값
if (method.equals(METHOD_GET)) { // 상수 : GET
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp); // doGET실행
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) { // POST
doPost(req, resp); // doPOST 실행
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
- HTTP Status code : client의 요청에 서버가 전송하는 결과코드
코드 | 메시지 | 설명 |
1XX | Informational(정보) | 정보 교환. |
2XX | Success(성공) | 데이터 전송이 성공적으로 이루어졌거나, 이해되었거나, 수락되었음. |
3XX | Redirection(방향 바꿈) | 서버가 클라이언트에게 요청할 주소를 전달. |
4XX | Client Error (클라이언트 오류) |
클라이언트 측의 오류. 주소를 잘못 입력하였거나 요청이 잘못 되었음. |
5XX | Server Error (서버 오류) |
서버 측의 오류. 서버가 요청을 받아서 처리하는 과정에서 에러가 발생 ⇒ 개발자 해결 해야하는 부분 |
- Servlet -> JSP
- url-mapping
- out.write()
- 협업의 어려움
실습
- servlet을 이용하여 times tables 출력
- url : http://localhost/TimesTablesServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TimesTablesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
//writer.println("<html>");
//writer.println("<head></head>");
writer.println("<style> td{ border:1px solid black; padding: 10px;} </style>");
//writer.println("<body>");
writer.println(" <table>");
for (int i = 1; i < 10; i++) {
writer.println(" <tr>");
for (int j = 2; j < 10; j++) {
writer.println(" <td>"+ j + " * "+ i +" = " + i*j +"</td>");
}
writer.println(" </tr>");
}
writer.println(" </table>");
//writer.println("</body>");
//writer.println("</html>");
//writer.flush();
//writer.close();
}
}
정리
- java 웹 어플리케이션 구조
- servlet 실습(현재시간, times tables)
- jsp의 탄생배경 이해