diff --git a/build.gradle b/build.gradle index 875389f..cf3790f 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,12 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + //JSP 추가 시작 + implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' + implementation 'jakarta.servlet:jakarta.servlet-api' //스프링부트 3.0 이상 + implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api' //스프링부트 3.0 이상 + implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl' //스프링부트 3.0 이상 + //JSP 추가 끝 compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' diff --git a/src/main/java/hello/servlet/domain/member/Member.java b/src/main/java/hello/servlet/domain/member/Member.java new file mode 100644 index 0000000..fc56ec1 --- /dev/null +++ b/src/main/java/hello/servlet/domain/member/Member.java @@ -0,0 +1,21 @@ +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; + } +} diff --git a/src/main/java/hello/servlet/domain/member/MemberRepository.java b/src/main/java/hello/servlet/domain/member/MemberRepository.java new file mode 100644 index 0000000..f1c4e0b --- /dev/null +++ b/src/main/java/hello/servlet/domain/member/MemberRepository.java @@ -0,0 +1,44 @@ +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 store = new HashMap<>(); + private static long sequence = 0L; + + private static final MemberRepository instance = new MemberRepository(); + + public static MemberRepository getInstance() { + return instance; + } + + // 싱글톤일 때는 private 으로 생성자 막아야 함. + 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 findAll() { + return new ArrayList<>(store.values()); + } + + public void clearStore() { + store.clear(); + } +} diff --git a/src/main/java/hello/servlet/web/servlet/MemberFormServlet.java b/src/main/java/hello/servlet/web/servlet/MemberFormServlet.java new file mode 100644 index 0000000..e6a248d --- /dev/null +++ b/src/main/java/hello/servlet/web/servlet/MemberFormServlet.java @@ -0,0 +1,40 @@ +package hello.servlet.web.servlet; + +import hello.servlet.domain.member.MemberRepository; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.PrintWriter; + +@WebServlet(name = "memberFormServlet", urlPatterns = "/servlet/members/new-form") +public class MemberFormServlet 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("\n" + + "\n" + + "\n" + + " \n" + + " Title\n" + + "\n" + + "\n" + + "
\n" + + " username: \n" + + " age: \n" + + " \n" + + "
\n" + + "\n" + + "\n"); + } +} diff --git a/src/main/java/hello/servlet/web/servlet/MemberListServlet.java b/src/main/java/hello/servlet/web/servlet/MemberListServlet.java new file mode 100644 index 0000000..310bcd5 --- /dev/null +++ b/src/main/java/hello/servlet/web/servlet/MemberListServlet.java @@ -0,0 +1,56 @@ +package hello.servlet.web.servlet; + +import hello.servlet.domain.member.Member; +import hello.servlet.domain.member.MemberRepository; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; + +// 저장된 모든 회원의 목록 조회 +@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 members = memberRepository.findAll(); + + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + PrintWriter w = response.getWriter(); + w.write(""); + w.write(""); + w.write(" "); + w.write(" Title"); + w.write(""); + w.write(""); + w.write("메인"); + w.write(""); + w.write(" "); + w.write(" "); + w.write(" "); + w.write(" "); + w.write(" "); + w.write(" "); + for (Member member : members) { + w.write(" "); + w.write(" "); + w.write(" "); + w.write(" "); + w.write(" "); + } + w.write(" "); + w.write("
idusernameage
" + member.getId() + "" + member.getUsername() + "" + member.getAge() + "
"); + w.write(""); + w.write(""); + } +} diff --git a/src/main/java/hello/servlet/web/servlet/MemberSaveServlet.java b/src/main/java/hello/servlet/web/servlet/MemberSaveServlet.java new file mode 100644 index 0000000..7331322 --- /dev/null +++ b/src/main/java/hello/servlet/web/servlet/MemberSaveServlet.java @@ -0,0 +1,47 @@ +package hello.servlet.web.servlet; + +import hello.servlet.domain.member.Member; +import hello.servlet.domain.member.MemberRepository; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.io.PrintWriter; + +@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 { + // html 에서 입력받은 데이터를 읽으려면 + 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("\n" + + "\n" + + " \n" + + "\n" + + "\n" + + "성공\n" + + "
    \n" + + "
  • id="+member.getId()+"
  • \n" + + "
  • username="+member.getUsername()+"
  • \n" + + "
  • age="+member.getAge()+"
  • \n" + + "
\n" + + "메인\n" + + "\n" + + ""); + } +} diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index f474ec3..2daa01b 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -8,6 +8,78 @@ \ No newline at end of file diff --git a/src/main/webapp/jsp/members.jsp b/src/main/webapp/jsp/members.jsp new file mode 100644 index 0000000..588d809 --- /dev/null +++ b/src/main/webapp/jsp/members.jsp @@ -0,0 +1,34 @@ +<%@ page import="hello.servlet.domain.member.MemberRepository" %> +<%@ page import="hello.servlet.domain.member.Member" %> +<%@ page import="java.util.List" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<% + MemberRepository memberRepository = MemberRepository.getInstance(); + List members = memberRepository.findAll(); +%> + + + + Title + + +메인 + + + + + + + <% + for (Member member : members) { + out.write(" \n"); + out.write(" \n"); + out.write(" \n"); + out.write(" \n"); + out.write(" \n"); + } + %> + +
idusernameage
" + member.getId() + "" + member.getUsername() + "" + member.getAge() + "
+ + diff --git a/src/main/webapp/jsp/members/new-form.jsp b/src/main/webapp/jsp/members/new-form.jsp new file mode 100644 index 0000000..2f21bba --- /dev/null +++ b/src/main/webapp/jsp/members/new-form.jsp @@ -0,0 +1,13 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Title + + +
+ username: + age: + +
+ + \ No newline at end of file diff --git a/src/main/webapp/jsp/members/save.jsp b/src/main/webapp/jsp/members/save.jsp new file mode 100644 index 0000000..e4757b8 --- /dev/null +++ b/src/main/webapp/jsp/members/save.jsp @@ -0,0 +1,29 @@ +<%@ page import="hello.servlet.domain.member.Member" %> +<%@ page import="hello.servlet.domain.member.MemberRepository" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<% + + // request, response 사용 가능 + 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); +%> + + + Title + + +성공 +
    +
  • id=<%=member.getId()%>
  • +
  • username=<%=member.getUsername()%>
  • +
  • age=<%=member.getAge()%>
  • +
+메인 + + \ No newline at end of file diff --git a/src/test/java/hello/servlet/domain/member/MemberRepositoryTest.java b/src/test/java/hello/servlet/domain/member/MemberRepositoryTest.java new file mode 100644 index 0000000..c1096b4 --- /dev/null +++ b/src/test/java/hello/servlet/domain/member/MemberRepositoryTest.java @@ -0,0 +1,50 @@ +package hello.servlet.domain.member; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +public 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()); + 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 result = memberRepository.findAll(); + + //then + assertThat(result.size()).isEqualTo(2); + assertThat(result).contains(member1, member2); + } +}