-
[스프링MVC - 1편] 회원관리 웹 애플리케이션 구현스프링&스프링부트 2025. 1. 5. 12:46
[ 서블릿 > JSP > MVC 패턴으로 구현 ]
회원 도메인 모델
@Getter @Setter public class Member { private Long id; private String username; private int age; public Member(){ } public Member(String username, int age) { this.username = username; this.age = age; } }
// 동시성 문제가 고려되어 있지 않음, 실무에선 ConcurrentHashMap, AtomicLong 사용 고려 public class MemberRepository { private static Map<Long, Member> store = new HashMap<>(); private static long sequence = 0L; // 싱글톤으로 생성 private static final MemberRepository instance = new MemberRepository(); public static MemberRepository getInstance() { return instance; } private MemberRepository() { } public Member save(Member member) { member.setId(++sequence); store.put(member.getId(), member); return member; } public Member findById(Long id){ return store.get(id); } public List<Member> findAll() { return new ArrayList<>(store.values()); } public void clearStore() { store.clear(); } }
class MemberRepositoryTest { // 싱글톤이기 때문에 new 로 생성 불가 - 스프링을 사용하면 스프링 자체가 싱글톤 보장 // MemberRepository memberRepository = new MemberRepository(); MemberRepository memberRepository = MemberRepository.getInstance(); @AfterEach void afterEach() { memberRepository.clearStore(); } @Test void save() { // given Member member = new Member("hello", 20); // when Member savedMember = memberRepository.save(member); // then Member findMember = memberRepository.findById(savedMember.getId()); Assertions.assertThat(findMember).isEqualTo(savedMember); } @Test void findAll() { // given Member member1 = new Member("member1" , 20); Member member2 = new Member("member2" , 30); memberRepository.save(member1); memberRepository.save(member2); // when List<Member> result = memberRepository.findAll(); // then Assertions.assertThat(result.size()).isEqualTo(2); Assertions.assertThat(result).contains(member1, member2); } }
회원 관리 웹 애플리케이션 - 서블릿 구현
1. MemberFormServlet - 회원 등록 폼
@WebServlet(name="memberFromServlet", urlPatterns = "/servlet/members/new-form") public class MemberFromServlet extends HttpServlet { private MemberRepository memberRepository = MemberRepository.getInstance(); @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"); } }
2. MemberSaveServlet - 회원 저장
@WebServlet(name="memberSaveServlet", urlPatterns = "/servlet/members/save") public class MemberSaveServlet extends HttpServlet { private MemberRepository memberRepository = MemberRepository.getInstance(); @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("MemberSaveServlet.service"); String username = request.getParameter("username"); int age = Integer.parseInt(request.getParameter("age")); Member member = new Member(username, age); memberRepository.save(member); response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter w = response.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>"); } }
3. MemberListServlet - 회원 목록
@WebServlet(name="memberListServlet", urlPatterns = "/servlet/members") public class MemberListServlet extends HttpServlet { private MemberRepository memberRepository = MemberRepository.getInstance(); @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Member> members = memberRepository.findAll(); response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter w = response.getWriter(); w.write("<html>"); w.write("<head>"); w.write(" <meta charset=\"UTF-8\">"); w.write(" <title>Title</title>"); w.write("</head>"); w.write("<body>"); w.write("<a href=\"/index.html\">메인</a>"); w.write("<table>"); w.write(" <thead>"); w.write(" <th>id</th>"); w.write(" <th>username</th>"); w.write(" <th>age</th>"); w.write(" </thead>"); w.write(" <tbody>"); /* -- 정적 html w.write(" <tr>"); w.write(" <td>1</td>"); w.write(" <td>userA</td>"); w.write(" <td>10</td>"); w.write(" </tr>"); */ for (Member member : members) { w.write(" <tr>"); w.write("<td>" + member.getId() + "</td>"); w.write("<td>" + member.getUsername() + "</td>"); w.write("<td>" + member.getAge() + "</td>"); w.write(" </tr>"); } w.write(" </tbody>"); w.write("</table>"); w.write("</body>"); w.write("</html>"); } }
템플릿 엔진으로
지금까지 서블릿과 자바 코드만으로 HTML을 만들었다
서블릿 덕분에 동적으로 원하는 HTML을 마음껏 만들 수있다 그런데, 코드에서 보듯이 이것은 매우 복잡하고 비효율적이다
자바 코드로 HTML을 만들어 내는 것 보다
차라리 HTML 문서에 동적으로 변경해야 하는 부분만 자바 코드를 넣을 수 있다면 더 편리할 것이다
이것이 바로 템플릿 엔진이 나온 이유이다
템플릿 엔진을 사용하면 HTML 문서에서 필요한 곳만 코드를 적용해서 동적으로 변경할 수 있다
템플릿 엔진에는 JSP, Thymeleaf, Freemarker, Velocity등이 있다
728x90'스프링&스프링부트' 카테고리의 다른 글
[스프링MVC - 1편] MVC 패턴 개요 (0) 2025.01.11 [스프링MVC - 1편] JSP 회원관리 웹 애플리케이션 만들기 (0) 2025.01.11 [스프링MVC - 1편] HTTPServletResponse (1) 2025.01.05 [스프링MVC - 1편] HTTP 요청 데이터 (2) 2025.01.02 [스프링MVC - 1편] HttpServletRequest (0) 2025.01.02