이 글은 김영한 강사님의 강의를 참고하여 작성하였습니다.
이 곳에서 가장 많이 다룰 것은 각각의 차이점이 될 것 같은데
이 중 핵심만 작성하기 위해 간결하게 작성하였다.
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter w = response.getWriter();
w.write("<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"/servlet/members/save\" method=\"post\">\n" +
" username: <input type=\"text\" name=\"username\" />\n" +
" age: <input type=\"text\" name=\"age\" />\n" +
" <button type=\"submit\">전송</button>\n" +
"</form>\n" +
"</body>\n" +
"</html>\n");
}
- 서블릿을 이용하니 일일히 service() 내에 '자바코드'를 이용해 HTML을 만들었다.
-> 그러다 보니 너무 복잡 비효율 적이다.
=> HTML을 분리하고 필요한 부분만 자바코드를 넣는 방법은 없을까? 🤔
=> 템플릿 엔진을 이용 (JSP, 타임리프..)하여 HTML 문서를 분리하고 필요 부분만 '자바 코드'를 써서 동적으로 변경하자
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'javax.servlet:jstl'
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/jsp/members/save.jsp" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-> 첫 줄은 JSP문서라는 뜻- JSP는 첫 줄을 제외하곤 거의 HTML이다.
- JSP는 서버 내부에서 서블릿으로 변환 됨
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// request, response 사용 가능
MemberRepository memberRepository = MemberRepository.getInstance();
System.out.println("save.jsp");
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
System.out.println("member = " + member);
memberRepository.save(member);
%>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
성공
<ul>
<li>id=<%=member.getId()%></li>
<li>username=<%=member.getUsername()%></li>
<li>age=<%=member.getAge()%></li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>
<% ~~ %>
: 자바 코드 입력 구간<%= ~~ %>
: 자바 코드 출력 구간
1. JSP가 너무 많은 역할을 가짐
• 비즈니스 로직부터 시작해 '뷰 렌더링'까지...
=> 유지보수의 어려움
2. 변경의 라이프 사이클
• 비즈니스 로직과 UI 등 서로에게 영향을 주지 않아야 함.
-> 변경의 라이플 사이클이 다른 둘을 '하나의 코드'로 관리한다
=> 좋지 않다 💦
3. 기능 특화의 필요
• JSP 처럼 '뷰 템플릿'은 화면 렌더링에 최적화 되어 있다.
-> 해당 본업만 시키자
- 컨트롤러
- HTTP 요청을 받아서 파라미터를 검증
- 비즈니스 로직을 호출한다. 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담아줌
=> 원래라면 비즈니스 로직을 담는 '서비스'라는 계층이 따로 있음.- 모델
- 뷰에 출력할 데이터를 담아둔다.
-> 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 됨.
-> 화면을 렌더링 하는 일에 집중할 수 있다.- 뷰
- 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다
- 여기서는 HTML을 생성하는 부분
@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/
new-form")
public class MvcMemberFormServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
/WEB-INF
- 이 경로에 있는 파일들은 '외부'에서 직접 호출이 불가하여 '컨트롤러'를 통해 호출이 가능dispatcher.forward()
- 서부 내부에서 일어나는 호출(다른 서블릿이나 JSP)
- redirect 의 경우 실제 '웹 브라우저(클라이언트)'에 요청 응답 등의 반복으로 호출된다는 것에서 둘의 차이가 있다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /save] -->
<form action="save" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
</body>
</html>
상대경로 사용
그렇게 되면 폼 전송시, "현재 url속한 계층 경로" + save가 호출
/servlet-mvc/members/save
1. 포워드 중복
-> View로 이동하는 코드가 항상 중복 호출 (메서드 또한..)
request.getAttribute(name)