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
728x90
'[ Spring ] > SpringMVC 1편' 카테고리의 다른 글
[Spring] Servlet과 JSP로 MVC 패턴 구현하기 (0) | 2022.02.18 |
---|---|
[Spring] MVC 패턴 (Model - View - Controller) (0) | 2022.02.18 |
[Spring] 서블릿으로 회원 관리 웹 애플리케이션 만들기 (0) | 2022.02.17 |
[Spring] HttpServletResponse / 응답 데이터 전달하는 방법 (0) | 2022.02.15 |
[Spring] HttpServletRequest / HTTP 요청 데이터를 얻는 3가지 방법 (0) | 2022.02.15 |