서블릿과 JSP

ikyeong·2023년 5월 16일
1

Spring-Study

목록 보기
4/9

01.서블릿

📌 Servlet vs Controller

  • Controller를 이용한 구현
@Controller
public class TwoDice { // 상속받지 않음
    @RequestMapping("/rollDice") // 메서드 단위로 매핑
    public void main(HttpServletResponse response) throws IOException {
        int idx1 = (int)(Math.random()*6)+1;
        int idx2 = (int)(Math.random()*6)+1;

        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        
        ...
    }
}
  • Servlet을 이용한 구현
@WebServlet("/rollDice2") // @Controller + @RequestMapping, 클래스 단위로 매핑
public class TwoDiceServlet extends HttpServlet { // HttpServlet을 상속
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        int idx1 = (int)(Math.random()*6)+1;
        int idx2 = (int)(Math.random()*6)+1;

        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        
        ...
    }
}

📌 02.서블릿의 생명주기

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
	@Override
	public void init() throws ServletException {  
		// 서블릿이 생성 또는 리로딩 될 때 한번만 수행
		System.out.println("[HelloSerlvet] init()");
	}
	   
	@Override // 호출될 때마다 반복적으로 수행
	public void service(HttpServletRequest request, HttpServletResponse response) {
		// 1. 입력
		// 2. 처리 
		// 3. 출력
		System.out.println("[HelloSerlvet] service()");
	}
	
	@Override   
	public void destroy() {   
		// 서블릿이 제거될 때 한번만 수행
		System.out.println("[HelloSerlvet] destroy()");  
	}
}

💡 서블릿은 1개의 인스턴스만 생성 (singleton)

요청마다 수행하는 작업이 같기때문에 인스턴스를 여러개 만들 필요가 없다


02.JSP (Java Server Page)

JSP는 HTML 코드안에 Java 코드가 있는 것
<%~%>안에 자바 코드를 넣어 사용


📌 JSP와 서블릿

JSP는 자동적으로 서블릿으로 변환된다!

  • twoDice.jsp
<%@ page contentType="text/html;charset=utf-8"%>
<%@ page import="java.util.Random" %>
<%-- <%! 클래스 영역 %> --%>
<%!  
	int getRandomInt(int range){
		return new Random().nextInt(range)+1;
	}
%>
<%-- <%  메서드 영역 - service()의 내부 %> --%>
<%
	int idx1 = getRandomInt(6);
	int idx2 = getRandomInt(6);
%>
<%-- <% html 코드는 out.println("...")로 변경 %> --%>
<html>
<head>
	<title>twoDice.jsp</title>
</head>
<body>
	<img src='resources/img/dice<%=idx1%>.jpg'>
	<img src='resources/img/dice<%=idx2%>.jpg'>
</body>
</html>

📌 JSP 호출 과정

💡 jsp파일이 첫번째로 호출될 때 서블릿 클래스로 변환

서블릿은 요청이 들어올때 인스턴스를 생성하는 lazy init 방식 ( vs 스프링은 early init 방식 )


📌 JSP의 기본 객체

생성하지 않고 사용할 수 있는 객체
request, response, session, application, out 등 존재

<%@ page contentType="text/html;charset=utf-8"%>
<%@ page import="java.util.Calendar" %>
<%
	//여기서 사용되는 request는 기본객체
	String year  = request.getParameter("year");
	String month = request.getParameter("month");
	String day   = request.getParameter("day");
	
	int yyyy = Integer.parseInt(year);
	int mm   = Integer.parseInt(month);
	int dd   = Integer.parseInt(day);
	
	// 2. 처리
	Calendar cal = Calendar.getInstance();
	cal.set(yyyy, mm - 1, dd);
	
	int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
	char yoil = " 일월화수목금토".charAt(dayOfWeek);
	
	// 3. 출력 
%>
<html>
<head>
	<title>yoilTeller.jsp</title>
</head>
<body>
	<h1><%=yyyy%>년 <%=mm%>월 <%=dd%>일은 <%=yoil%>요일입니다.</h1>
</body>
</html>

📌 유효범위와 속성

pageContext, application(공통 저장소), session(클라이언트 저장소,쿠키 이용,서버부담이 제일 큼), request(요청할때마다 생김)

  • 자바 Web App의 저장공간
기본 객체유효 범위설명
pageContext1개의 JSP 페이지해당 JSP 내부에서만 접근가능, 페이지 당 1개
request1+개의 JSP 페이지다른 JSP로 전달 가능, 요청 당 1개
sessionn개의 JSP페이지로그인부터 로그아웃까지, 클라이언트 당 1개, 서버부담이 큼, 개별 데이터 저장
applicationcontext 전체context 내부의 어디서든 접근 가능, 모든 클라이언트가 공유, context 당 1개, 전체 데이터 저장
  • 저장공간 관련 메서드
메서드설명
setAttribute(String name, Object value)지정된 이름으로 속성값을 저장
getAttribute(String name)지정된 이름으로 저장된 속성값을 반환
removeAttribute(String name)지정된 이름의 속성을 삭제
getAttributeNames()기본 객체에 저장된 모든 속성의 이름을 반환

📌 URL 패턴

@WebServlet 어노테이션으로 서블릿을 URL에 매핑할 때 사용

@WebServlet(urlPatterns={"/hello","/hello/*"}, loadOnStartup=1) 이런식으로 urlPatterns 속성을 통해 여러가지 URL을 매핑할 수 있다 (여기서 loadOnStartup은 미리 초기화를 하도록하는 옵션)

우선순위종류URL pattern매핑되는 URL
1exact mapping/login/hello.dohttp://localhost/ch2/login/hello.do
2path mapping/login/*http://localhost/ch2/login/ 아래의 모든 URL
3extension mapping*.dohttp://localhost/ch2/login/hello.do 와 같이 확장자가 do인 URL
4default mapping/http://localhost/ch2/ 아래의 모든 URL

💡 default mapping은 정적 리소스를 처리한다

나머지 세가지에서 매핑이 된다면 동적 리소스(서블릿) 처리를 해주고, 매핑되는 URL이 없는 경우 default mapping에서 처리

💡 스프링 개발에서는 servlet, jsp의 역할을 DispatcherServlet이 수행

DispatcherServlet 내부에서 매핑처리(@RequestMapping(...))


📌 EL(Expression Language)

<%=value%>${value}로 사용가능


📌 Filter

공통적인 요청의 전처리, 응답의 후처리에 사용 (스프링의 AOP 개념과 비슷)

@WebFilter(urlPatterns="/*") //수행시간을 측정하는 Filter
public class PerformanceFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 초기화 작업
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 1. 전처리 작업
		long startTime = System.currentTimeMillis();

		// 2. 서블릿 또는 다음 필터를 호출
		chain.doFilter(request, response); //서블릿 호출
		
		// 3. 후처리 작업
		System.out.print("["+((HttpServletRequest)request).getRequestURI()+"]");
		System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
	}

	@Override
	public void destroy() {
		// 정리 작업
	}
}

0개의 댓글