[Servlet] Web Server, WAS, Servlet
WAS vs. Web ServerWeb Server와 WAS(Web Application Server)는 같은 의미의 용어인가 싶지만 깊이 파보면 그 미묘한 차이가 있다. 단순히 직역하였을 때 WAS는 웹에서 "Application" 기능을 제공하는 서버이고, Web S
brothergiven.tistory.com
Servlet과 JSP
Spring MVC는 MVC 패턴의 사고방식에 따라 효율적으로 웹 애플리케이션을 만들 수 있는 스프링의 기능이다. Spring 등장 전 자바 진영의 WAS는 JSP와 Servlet의 조합으로 주로 작성되었는데, 이 방법을 한 번 뜯어보자.
@WebServlet(name = "memberSaveServlet", urlPatterns = "/servlet/members/save")
public class MemberSaveServlet extends HttpServlet {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
String username = req.getParameter("username");
int age = Integer.parseInt(req.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
res.setContentType("text/html");
res.setCharacterEncoding("utf-8");
PrintWriter w = res.getWriter();
w.write("<html>\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
"</head>\n" +
"<body>\n" +
"성공\n" +
"<ul>\n" +
" <li>id=" + member.getId() + "</li>\n" +
" <li>username=" + member.getUsername() + "</li>\n" +
" <li>age=" + member.getAge() + "</li>\n" +
"</ul>\n" +
"<a href=\"/index.html\">메인</a>\n" +
"</body>\n" +
"</html>");
}
}
Servlet/JSP는 이제는 Spring MVC에 의해 대체되어 잘 사용되지 않는 기술이다. 위 코드는 Servlet으로 구현한 새로운 사용자를 등록하는 코드인데, 위 코드의 단점을 찾아보자.
1. HTML을 Java 코드 안에서 직접 작성해야 함
Servlet을 사용하여 Http Request와 Http Response를 개발자가 쉽게 다룰 수 있었지만, Response에다 HTML 문서를 직접 자바 코드로 작성하여 넣어준 다음 클라이언트에게 전송해줘야 하므로 가독성이 매우 떨어지고, 수정이 어렵다는 큰 단점이 있었다.
2. 코드 중복이 많다
res.setContentType(), PrintWriter w = res.getWriter() 등 기능에 따라 코드가 완전히 달라지는 게 아니라 Servlet을 사용하여 Response를 보내기 위해 반드시 적어줘야 하는 코드들이 보인다.(HTML 태그들도)
위 문제를 해결하기 위해 JSP가 등장했다. JSP는 HTML 안에서 Java 코드를 사용할 수 있도록 도와주는 기술이다.
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<html>
<head>
<title>로그인</title>
</head>
<body>
<h2>로그인</h2>
<form method="post" action="login.jsp">
아이디: <input type="text" name="username"><br>
비밀번호: <input type="password" name="password"><br>
<input type="submit" value="로그인">
</form>
</body>
</html>
위 JSP 코드는 아래 Servlet 코드와 거의 비슷한 모습으로 변환된다.
@WebServlet(name = "memberFormServlet", urlPatterns = "/servlet/members/new-form") // 회원정보 입력할 수 있는 form
public class MemberFormServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("/servlet/members/new-form : " + req);
res.setContentType("text/html");
res.setCharacterEncoding("utf-8");
// Servlet 사용법 1 : writer 사용하여 HTML form 직접 작성 후 전송
PrintWriter w = res.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");
}
}
확실히 JSP를 사용한 코드가 HTML을 깔끔하게 작성하고, 로직이 필요하다면 Java 코드를 사용하여 필요한 작업을 적용하여 더 깔끔하다. 하지만 여전히 필요한 비즈니스 로직이 많아질 경우 Java 코드가 HTML 안에 들어가서 가독성이 문제가 될 수 있다. 또한 하나의 파일이 두 가지 역할을 하며(Java, HTML) 둘 사이의 변경의 라이프 사이클이 달라 유지보수가 힘들다는 점, SQL 실행 시 SQL Injection의 위험 등의 이유로 이 두 부분을 분리하여 생각하고 싶은데...
MVC
앞서 본 것처럼 하나의 JSP 또는 Servlet이 처리하던 것을 컨트롤러와 뷰 라는 영역으로 역할을 나눈 디자인 패턴을 뜻한다. 더 엄밀히 말하자면:
UI를 가진 애플리케이션을 개발할 때 적용하는 가장 일반적인 설계 개념인 MVC(Model-View-Controller)란 애플리케이션을 모델, 뷰, 컨트롤러로 나누어 관리하는 디자인 패턴이다. UI와 비즈니스 로직을 분리하여 유지보수성과 확장성을 높인다는 특징이 있다. 각 역할은 다음과 같은 처리를 담당한다.
- Controller: client의 Http 요청을 받아서 파라미터를 검증하고 비즈니스 로직을 처리한다. 그리고 뷰에 전달할 결과 데이터를 조회하여 모델에 담는다.
- Model : 뷰에 출력할 데이터를 담는다. 뷰는 비즈니스 로직 또는 데이터 접근을 모른 채로 모델에 있는 데이터만 꺼내서 화면을 렌더링하면 된다.
- View : 사용자에게 보여지는 부분, HTML을 생성한다.
JSP/Servlet에서 Controller 사용 예시
@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("MvcMemberListServlet.service");
List<Member> members = memberRepository.findAll();
request.setAttribute("members", members);
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
위 Servlet 클래스는 Controller의 역할을 하며, 요청이 들어오면 모델에 데이터를 담아서 해당 데이터와 함께 요청에 맞는 View 템플릿(JSP 파일)로 경로를 이동시켜준다.
'웹' 카테고리의 다른 글
[HTTP] 80 vs. 8080 (0) | 2025.02.28 |
---|---|
[Servlet] Web Server, WAS, Servlet (1) | 2025.02.10 |
[Web] SPA/MPA, CSR/SSR (0) | 2025.02.06 |