프로젝트 시작 전 설정
요구사항 분석
상품 도메인 모델
- 상품 ID
- 상표명
- 가격
- 수량
상품 관리 기능
- 상품 목록
- 상품 상세
- 상품 등록
- 상품 수정
MVC를 사용하고 있으므로 항상 컨트롤러를 통해 뷰가 호출된다
상품 수정폼을 눌러서 수정하기 누르면 상품 상세로 리다이렉트한다
업무 진행
디자이너 : 디자인 결과물을 웹 퍼블리셔에게 넘겨준다
웹 퍼블리셔 : 디자이너에게 받은 디자인을 기반으로 HTML, CSS를 만들어 개발자에게 제공
백엔드 개발자 : 디자이너, 웹 퍼블리셔를 통해 HTML 화면이 나오기 전까지 시스템과 핵심 비즈니스 모델 설계
이후 HTML이 나오면 이 HTML을 뷰 템플릿으로 변환해서 동적으로 화면 제어 그리고 웹 화면의 흐름 제어
위 진행 방식은 프론트엔드 개발자가 없는 경우의 업무이고, 프론트엔드 개발자가 있다면 백엔드 개발자는
HTML 뷰 템플릿을 직접 만지는 대신에 HTTP API를 통해 웹 클라이언트가 필요로 하는 데이터와 기능만 제공하면 된다
상품 도메인 개발
Item - 상품 객체
hello/itemservice/domain/item/Item.class
Getter Setter 사용을 위해 롬복 어노테이션 @Getter @Setter를 삽입한다
@Data는 핵심 도메인 모델에 사용하기 되게 위험하다. 예측되지 못하게 막 동작할 수 있기 때문이다
DTO의 경우에는 써도 괜찮다
Integer인 이유는 price와 quantity가 입력이 안된 경우도 고려하는 것이다.
int로 쓰게 되면 0이라도 들어가야 한다 그러므로 null이 들어갈 수 있는 Integer 사용
기본 생성자를 만들었다
id를 제외한 생성자를 만들었다
ItemRepository - 상품 저장소
hello/itemservice/domain/item/ItemRepository.class
원래는 패키지 분리할 수 있는데, 지금은 프로젝트가 작아서 분리하지 않았다
@Repository는 @Component가 들어있어서 컴포넌트 스캔의 대상이 된다
Map에서 item 저장소니까 key는 Long 타입이다 item의 id가 Long 타입이므로
실제론 HashMap 사용하면 안된다 -> 멀티쓰레드 환경에서 여러개가 동시에 store에 접근하게 되면 해쉬맵 쓰면 안된다
사용하고 싶다면 ConcurrentHashMap<> 사용해야한다 또, sequence에서 long말고 atmoic long 등등 다른걸 써야함
정확하게 하자면 update 메서드에서 updateParam 별도의 객체를 만드는게 맞다
parameterDto와 같이 객체를 만들고 저 id 제외한 파라미터 3개를 딱 넣어놓는게 맞다 원래는
근데 프로젝트가 작고 인식할 수 있는 범위 내에 있으니까 저렇게 한거다...
store.clear() 사용시 해쉬맵에 있는 데이터가 다 날라간다
ItemRepositoryTest - 상품 저장소 테스트
test/java/hello/itemservice/domain/item/ItemRepositoryTest.class
최근 Junit5에는 public이 없어도 된다
@AfterEach은 테스트 하나하나가 끝날때마다 동작시켜준다. 데이터 지우는 동작을 테스트 끝날때마다 해줌
@Test 테스트에 붙임
//given //when //then이 필요하다
별 비즈니스 로직이 없어서 서비스는 만들지 않았다
상품 서비스 HTML
부트 스트랩을 https://getbootstrap.com 에서 다운로드 받은 후 bootstrap.min.css파일을
resources/static/css/bootstrap.min.css 이렇게 추가한다.
localhost 페이지에서 위 페이지가 안 열릴 경우 out 폴더를 지웠다가 서버를 재시작한다.
그리고 html 파일을 하나하나 다 추가한다
상품 목록 - 타임리프
BasicItemController
hello/itemservice/web/item/basic/BasicItemController.class
생성자 주입으로 스프링 빈으로 등록하는 생성자가 하나뿐이기 때문에 생략가능하고
@RequiredArgsConstructor가 final이 붙은 멤버변수만 사용해서 생성자를 자동으로 만들어준다
final을 빼면 ItemRepository 의존관계 주입이 안된다
아이템 목록을 출력하기 위해 itemRepository에서 다 찾아와서 addAttribute해서 items를 넣는다
basic/items 위치에 뷰를 만든다
아이템 목록을 보고싶은데 데이터가 하나도 없으면 제대로 안 나오기 때문에 테스트용 데이터를 추가하였다
html을 동적으로 만든거고 정적으로 만드려면 타임리프로 만들어야 한다
상품 상세
아래 코드를 BasicItemController에 추가한다
itemId가 들어오므로 PathVariable로 받는다 그리고 그 상품ID로 상품을 조회하고 모델에 담아둔다
그리고 뷰를 호출한다
상품 등록 폼
아래 코드를 BasicItemController에 추가한다
Form을 보여만주는거고 데이터를 저장하는 것이 아니므로 간단하다
상품 등록 처리- @ModelAttribute
상품 등록 폼은 다음 방식으로 서버에 데이터를 전달한다
POST-HTML Form
content-type: application/x-www-form-urlencoded
메세지 바디에 쿼리 파라미터 형식으로 전달 itemName=item&price=10000&quantity=10
RequestParam 3개 받는 과정 대신 @ModelAttribute 어노테이션으로 간단하게 코드를 수정할 수 있다
@ModelAttribute("item") 으로 객체를 생성해주고 객체를 Model에 넣어주는 역할 두 가지를 수행한다
지정한 이름으로 Model에 넣어주는 것이다
모델에 데이터를 담을 떄는 이름이 필요하다
"item" 이렇게 지정해주지않으면 클래스명의 앞글자를 소문자로 바꿔서 그 이름을 모델의 attribute에 넣어준다
Item -> item 이렇게.
'spring' 카테고리의 다른 글
[스프링 교과서] 스프링 컨텍스트: 빈 정의 (2) | 2024.08.23 |
---|---|
[스프링 교과서] 기초 (0) | 2024.08.23 |
[Spring MVC 1편] 스프링 MVC - 기본 기능 (0) | 2024.08.10 |
[Spring MVC 1편] 스프링 MVC- 구조 이해 (0) | 2024.08.09 |
[Spring MVC 1편] MVC 프레임워크 만들기 (2) | 2024.08.08 |