@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();
...
}
}
@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();
...
}
}
@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()");
}
}
요청마다 수행하는 작업이 같기때문에 인스턴스를 여러개 만들 필요가 없다
JSP는 HTML 코드안에 Java 코드가 있는 것
<%~%>안에 자바 코드를 넣어 사용
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>
서블릿은 요청이 들어올때 인스턴스를 생성하는 lazy init 방식 ( vs 스프링은 early init 방식 )
생성하지 않고 사용할 수 있는 객체
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 | 1개의 JSP 페이지 | 해당 JSP 내부에서만 접근가능, 페이지 당 1개 |
request | 1+개의 JSP 페이지 | 다른 JSP로 전달 가능, 요청 당 1개 |
session | n개의 JSP페이지 | 로그인부터 로그아웃까지, 클라이언트 당 1개, 서버부담이 큼, 개별 데이터 저장 |
application | context 전체 | context 내부의 어디서든 접근 가능, 모든 클라이언트가 공유, context 당 1개, 전체 데이터 저장 |
메서드 | 설명 |
---|---|
setAttribute(String name, Object value) | 지정된 이름으로 속성값을 저장 |
getAttribute(String name) | 지정된 이름으로 저장된 속성값을 반환 |
removeAttribute(String name) | 지정된 이름의 속성을 삭제 |
getAttributeNames() | 기본 객체에 저장된 모든 속성의 이름을 반환 |
@WebServlet 어노테이션으로 서블릿을 URL에 매핑할 때 사용
@WebServlet(urlPatterns={"/hello","/hello/*"}, loadOnStartup=1)
이런식으로 urlPatterns 속성을 통해 여러가지 URL을 매핑할 수 있다 (여기서 loadOnStartup은 미리 초기화를 하도록하는 옵션)
우선순위 | 종류 | URL pattern | 매핑되는 URL |
---|---|---|---|
1 | exact mapping | /login/hello.do | http://localhost/ch2/login/hello.do |
2 | path mapping | /login/* | http://localhost/ch2/login/ 아래의 모든 URL |
3 | extension mapping | *.do | http://localhost/ch2/login/hello.do 와 같이 확장자가 do인 URL |
4 | default mapping | / | http://localhost/ch2/ 아래의 모든 URL |
나머지 세가지에서 매핑이 된다면 동적 리소스(서블릿) 처리를 해주고, 매핑되는 URL이 없는 경우 default mapping에서 처리
DispatcherServlet 내부에서 매핑처리(@RequestMapping(...))
<%=value%>
를 ${value}
로 사용가능
공통적인 요청의 전처리, 응답의 후처리에 사용 (스프링의 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() {
// 정리 작업
}
}