[ Spring ]/SpringMVC 1편

[Spring] JSP로 회원 관리 웹 애플리케이션 만들기

쿠릉쿠릉 쾅쾅 2022. 2. 18. 04:51
728x90

 

회원 관리 웹 애플리케이션 요구사항

  • 회원 정보
    • 이름 : username
    • 나이 : age
  • 기능 요구사항
    • 회원 저장
    • 회원 목록 조회

 

 

🔍회원 도메인 모델

📌 Member 클래스

package hello.servlet.domain.member;

import lombok.Getter;
import lombok.Setter;

@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;
    }
}
  • id는 Member를 회원 저장소에 저장하면 회원 저장소가 할당한다.

 

🔍 회원 저장소

📌 MemberRepository 클래스

package hello.servlet.domain.member;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 동시성 문제가 고려되어 있지 않음. 실무에서는 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();
    }
}
  • 회원 저장소는 싱글톤 패턴을 적용했다.
    • 스프링을 사용하면 스프링 빈으로 등록되면서 싱글톤 패턴이 보장이 되지만, 지금은 최대한 스프링 없이 서블릿만으로 구현하기 위해서 getInstance() 메서드를 통해 싱글톤 패턴을 적용했다.

 

🔍 회원 저장소 테스트 코드

📌 MemberRepositoryTest 클래스

package hello.servlet.domain.member;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;


class MemberRepositoryTest {

    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());
        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
        assertThat(result.size()).isEqualTo(2);
        assertThat(result).contains(member1, member2);
    }

}
  • 회원을 저장하고 목록을 조회하는 테스트 코드 작성
  • 각 테스트가 끝나고 다음 테스트에 영향을 주지 않기 위해 @AfterEach 를 통해 각 테스트의 저장소를 초기화한다.

 


 

JSP로 회원 관리 웹 애플리케이션 만들기

  • JSP를 사용 하려면 build.gradle에 라이브러리를 추가해야한다.
//JSP 추가 시작
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'javax.servlet:jstl'
//JSP 추가 끝

 

🔍 회원 등록 폼

📌new-form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<html>
<head>
    <meta charset="UTF-8">
    <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>
  • JSP 문서를 작성할 때  <%@ page contentType="text/html;charset=UTF-8" language="java" %> 를 적고 시작해야 한다.
  • 사이트 주소 : http://localhost:8080/jsp/members/new-form.jsp
    • .jsp 까지 추가해야한다.

 

🔍 회원 저장

📌 save.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 사용 가능 → jsp가 servlet 으로 변환되어 사용되기 때문에 사용 가능하다.
    MemberRepository memberRepository = MemberRepository.getInstance();

    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);

%>

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</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>
  • JSP는 자바 코드를 그대로 다 사용할 수 있다.
  • <%@ page import="hello.servlet.domain.member.MemberRepository" %> 
    • 자바의 import문과 같다.
  • <% ~~ %>
    • 이 부분에 자바 코드를 입력할 수 있다.
    • request 와 response 객체를 사용할 수 있다. → JSP는 서버 내부에서 서블릿으로 변환되기 때문이다.
  • <%= ~~ %>
    • 이 부분에 자바 코드를 입력하면 출력이 된다.

 

🔍회원 목록

📌 members.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ page import="java.util.List" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>

<%
    MemberRepository memberRepository = MemberRepository.getInstance();
    List<Member> members = memberRepository.findAll();
%>

<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<a href="/index.html">메인</a>
<table>
     <thead>
     <th>id</th>
     <th>username</th>
     <th>age</th>
     </thead>
     <tbody>

    <%
         for (Member member : members) {
         out.write(" <tr>");
         out.write(" <td>" + member.getId() + "</td>");
         out.write(" <td>" + member.getUsername() + "</td>");
         out.write(" <td>" + member.getAge() + "</td>");
         out.write(" </tr>");
         }
    %>

     </tbody>
</table>
</body>
</html>

 

 

 

💡 JSP의 한계

  • JSP를 통해 뷰를 생성하는 HTML 작업이 깔끔해지고 중간중간 동적으로 변경이 필요한 부분에만 자바 코드를 적용할 수 있다.
  • 그러나 JSP에 비즈니스 로직도 있고 뷰도 있다. 너무 많은 역할을 한다. 이것을 나눌 필요가 있다.

 


👀 참고 자료

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

728x90