당니의 개발자 스토리

홈 화면과 레이아웃 본문

스프링/실전! 스프링 부트와 JPA 활용1

홈 화면과 레이아웃

clainy 2024. 5. 12. 02:10

홈 화면과 레이아웃

여러분 이제 드디어 웹계층을 개발해보겠습니다. 실제 지금까지 만든 베이스 코드를 기반으로 화면을 하나씩 만들어가는 거죠. 실제 동작하는 화면을 만드는 신나는 시간입니다.

먼저 웹계층 개발에 목차를 말씀드리면,

제일 처음에 홈 화면이랑 레이아웃이 어떻게 되는지 설명을 해 드릴 거고요. 참고로 여기서는 타임리프로 어떻게 구성하는지 쭉 해볼 겁니다.

자 그리고 회원을 등록하고 목록을 조회하는 회원 기능, 그 다음에 상품을 등록하고 목록을 뿌리고 상품을 수정하는 기능을 하면서 뭘 할 거냐면 제가 여러분께 변경 감지와 병합(merge)이라는 것을 설명 드릴 거에요.

뭐냐면 jpa에서 상품 수정 다음에 바로 할 건데, 어떻게 데이터를 수정하는 게 올바른 방법인가에 대해서 변경 감지와 병합(merge)으로 설명을 해드릴 겁니다.

수정하는 것을 왜 이렇게 뒤에 하냐고 의아하실 수 있는데 병합 때문에 그래요. 병합이라는 것을 이해를 하려면 문맥이 있어야 되거든요. 뭔가 데이터가 어느정도 화면에서 넘어오고 이런게 있어야 병합이라는게 더 이해하기 쉽기 때문에 제가 일부러 뒤로 밀었습니다.

그리고 이제 상품을 주문하는 화면을 만들고 주문 목록을 검색하고 취소하는 화면을 만들어 보겠습니다.

자 이번 시간에는 이제 홈 화면과 레이아웃 입니다.

제일 먼저 저희가 컨트롤러 패키지를 여기다 만들 거구요. 그 다음에 HomeController 라는 클래스를 만들 겁니다.

여기서 이제 스프링 @Controller를 하고 그 다음에 @RequestMapping("/")로 잡을 겁니다. "/"로 잡으면 그냥 첫번째 화면이 여기로 잡히는 거겠죠.

자 이렇게 한 다음에 return 하고 home 이라고 할 거에요. 이게 무슨 뜻이냐면, 이렇게 하면 home.html 로 찾아가서 타임리프 파일을 찾아가게 됩니다.

자 그리고 혹시 로그도 한번 찍어 볼게요.

보통 로그를 org.slf4j 를 써야 돼요. 저희가 slf4j 를 통해서 로거를 사용하기 때문에

이런식으로 log를 뽑을 수 있는데 이거를

@Slf4j annotation으로 lombok 을 쓰면 방금 그거랑 똑같은 코드를 쓸 수 있습니다.

log.info로 찍어볼게요. 이렇게 하면 home controller에 대한 게 이제 찍히게 됩니다.

자 그러면 이제 이 home 파일로 가게 해야 되겠죠.

그러면 resources/templates 에다가 home.html을 만들어야 합니다.

그래서 resources/templates 에다가 이제 타임리프 템플릿을 등록을 해야 됩니다. 자 근데 이 강의의 핵심이 화면을 찍는 게 핵심이 아니기 때문에 가급적인 화면 관련한 건 복붙을 많이 하겠습니다.

이렇게 복붙을 했습니다.

보시면 html에 이것만 잘 보시면 됩니다. namespace를 이 th 라고 적어줬습니다. 타임리프는 이렇게 관례상 th를 보통 쓰거든요. 그럼 이 th를 가지고 여기 있는 속성들을 쓸 수가 있습니다.

근데 다른 거는 보시면 대체로 뭔가 정적으로 쭉 뿌리면 될 것 같은데

이게 있습니다. header에 replace 해가지고 이거 fragment 라고 되어있죠. 이건 뭔가 include 하는 거예요. JSP로 따지면 include 처럼, 실제 렌더링 될 때 여기 있는 거를 fragment header로 바꿔치기 하는 거예요.

얘도 보면 자주 사용하는 거를 bodyHeader, 밑에 footer 이렇게 나눠서 import를 해서 쓸 거에요.

자 그래서 여기 템플릿에 디렉토리를 fragments 만들어주고,

여기에다가 첫번째 헤더를 먼저 만들어 볼게요.

그런데 일단 하기 전에 한번 돌려볼게요. 점진적으로 하는게 중요하니까. home이 일단 들어가지는지, 저희가 만든 log가 일단 찍히는지 먼저 한번 볼게요.

JpashopApplication를 돌리고 localhost:8080에 들어가면,

에러가 나네요. 지금 뭔가 문법에 문제가 있다고 나오죠.

자 보니까 템플릿에 제가 이 fragments/header를 replace 해서 이렇게 뭔가 땡기려고 했는데 없다고 나오죠.

그래도 어쨌든 이거를 탔겠죠. 제가 로거 찍었어요. 이걸 타고 home으로 가는 거니까,

항상 컨트롤러에 먼저 온 다음에 컨트롤러에서 View로 렌더링을 했는데 지금 에러가 나는 상황이란 말이에요.

그러면 "home controller"은 정상적으로 찍혔는지 확인해 볼게요.

자 여기 보시면 로거는 home controller 제대로 찍혔죠? 화면을 넘어가서 오류가 발생했구나 보시면 됩니다.

자 fragments에 header를 넣어볼게요.

그 다음에 붙여넣기 하면

이렇게 됩니다. 이런 식으로 bodyHeader랑 footer를 차례대로 복붙 하겠습니다.

이제 한번 다시 돌려볼게요.

보시면 home controller에서 필요한 bodyHeader, header, footer를 다 이렇게 파일에서 찾아서 replace 하는 거예요.

즉, fragments의 header라는 위치에서

이 header를 갖다가 들고와서

여기를 replace 하는 거예요. 자 이제 localhost:8080을 refresh 해보면,

잘 뿌려지는데 뭔가 간지가 안나죠. 아 뿌려지긴 하는구나 라고 보시면 되고, 여기서 뭐가 빠졌냐면 css나 그런 게 적용이 안되어 있는거죠. 일단 정말 순수하게 html만 적용이 되있는 상황이구요. 우선 그걸 설명하기 전에 지금 보면 저는 뭘 사용했냐면,

일단 레이아웃 먼저 설명을 드릴게요.

타임리프 페이지에 가셔서 Layouts에 들어가면

몇가지 방법들이 있다고 합니다. 하나는 뭐냐면 Include Style의 레이아웃과 계층형 Hierarchical Style의 레이아웃이 있다고 하는데, 저는 지금 Include Style의 레이아웃을 쓴 거에요. 이게 약간 무식한 방법이죠. 왜 무식하냐면 얘는 계속 Include를 해줘야 되거든요.

근데 여러분 실무에서 지금 제가 만약에 회원 가입이나 회원 목록 파일을 만들더라도 저는 지금

이 스타일에서 이걸 계속 include 해줘야 돼요. header랑 footer, 뭐 이런 거를 계속 include 해줘야 되는데 만약에 여러분이 실무에서 이 코드들에 대한 중복을 지금 없애고 싶다 하면 그 여기 보면 이 Hierarchical Style Layout을 적용하시면 돼요. 메뉴얼을 보고 하시면 됩니다.

그러면 아예 이런 코드도 다 중복을 없앨 수 있어요.

이렇게 이런 거 자체가 다 없어도

내가 딱 원하는 부분의 데이터만 코딩을 해서 파일로 만들어 놓을 수 있거든요.

그런 식으로 하는 거를 계층 스타일의 레이아웃이라고 해요. 근데 예제에서 이걸 쓰지 않는 이유는 제가 실무에서 하면 이걸 쓸 것 같은데 결국 이걸 하면 또 세팅이 들어가고 막 이걸 위한 설명을 또 한참 해야 돼요.

근데 지금 우리는뭔가 화면 베이스에 뭔가를 쭉 설명드리는 것보다는 어쨌든 화면은 최대한 심플하게, 쉽게 코드 중복이 되더라도 좀 약간 단순하게 이해를 시켜 드리는 게 더 나을 것 같은 선택이라고 생각해서 그냥 정말 단순한 include 스타일의 레이아웃을 계속 사용하겠습니다.

그래서 여러분이 타임리프를 더 심도있게 쓰려면 메뉴얼을 읽어보시고 적용하시면 됩니다. 보면 샘플도 많이 있어서 되게 쉽게 쓰실 수 있어요.

그리고 이제 화면을 하니까 제가 처음에 그 DevTools 기억나시죠.

여기 보면 restartedMain 이라고 SpringBoot를 딱 실행시키면 뜨는데, 여기 라이브러리 한번 보여드리면

spring-boot-devTools 들어가 있죠. 이게 들어가 있으면 기본적으로 띄우면 Spring Boot가 개발할 때 restartedMain으로 뜨게 됩니다.

그러면 기본적으로 이런 파일들에 대해서 캐싱을 안해요. 그래서 뭔가 변경하고 리컴파일 하면 반영이 돼서 변형된 게 바로 확인할 수 있도록 DevTools가 다 해주거든요.

만약에 제가 회원 기능을

이렇게 적었어요. 그러면 이제 재시작 안하고 리컴파일만 해주면,

이거를 누르시고 localhost:8080을 다시 refresh 하시면

바껴있는 걸 보실 수 있습니다. 자 다시 원상복구하고, 리컴파일 Command + Shift + F9 눌러서 보면,

다시 돌아가 있죠. 그냥 복습 차원에서 말씀드렸습니다. 계속 변경할 때마다 막 서버 다시 띄우면 되게 짜증나니까요.

자 그리고 이제 뷰 리소스를 한번 등록을 해볼게요. 화면과 관련된 거를 좀 이쁘게 하려면 화면과 관련된 리소스가 필요하겠죠.

자 이거는 여러분들 잘 아시는 getbootstrap 여기 들어가시면 됩니다.

그래서 이거를 다운로드 받으시면 됩니다.

버전 업이 뭐 크게 메이저가 되지 않는 이상은 크게 차이는 안 날 거에요.

자 다운로드를 받으시면,

css랑 js가 있는데, 이거를 여러분들이 복사를 다 하시면 됩니다. 어디로?

자 여기 보시면 resources에 static 이라고 있어요. 여기에다가 다 복붙을 해놓는 겁니다.

이렇게 선택하셔서 복사하고,

static 컨텐츠 밑에 붙여넣기를 하시면 됩니다.

그러면 resource에 static에 js랑 css가 있죠. spring boot가 기본적으로 이 static 폴더에 있는 것은 그냥 정적 콘텐츠로 바로 적용이 됩니다.

이 상태에서 다시 돌려 보겠습니다.

잘 뜬거 확인 하실 수 있죠. 혹시라도 잘 안 될 수가 있어요. 제가 강제로 복사 붙여넣기를 했기 때문에 인텔리 제이가 인식을 잘 못 할 수도 있거든요.

그럴 때는 강제로 Synchronize를 해주고

Build에서 Build Project를 다시한번 해주세요. 그러면 인텔리 제이가 정확하게 인식을 하거든요. 그리고 나서 서버를 다시 띄우면 보통은 이제 잘 됩니다. 다시 refresh 해주면 잘 됩니다.

자 그런데 지금 보면 약간 이 디자인이 좀 안맞죠. 이게 사실 bootstrap에서 제가 예전 버전을 디자인 했던 것을 가져온 거에요.

그래서 제가 예제로 드리는 jumbotron과 관련된 파일이 있거든요. css에 추가로 필요합니다.

첨부해놨으니까 이 코드는 복사해서 붙여주세요.

자 이제 refresh 하면 이쁘게 나옵니다.

자 이렇게 해서 이제 기능을 회원가입, 목록부터 이렇게 하나씩 쭉 추가를 할 겁니다.

자 이제 이번 시간 정리할게요. Command + E를 하면 최근에 썼던 리소스가 나오거든요.

자 여기에서 "/"로 들어오면 컨트롤러에서 view로 넘어가겠죠? 그럼 home 으로 넘어가고

얘는 제가 include 스타일로 이 리소스들을 include 했습니다. 헤더에 가보면,

얘가 지금 css를 쓰는 거죠. 이렇게 Bootstrap css랑 그 다음에 jumbotron css를 가지고 있는 거죠.

그리고 bodyHeader도 뭔가 데이터를 가지고 있고 footer도 어느정도 정보를 들고 있는 거죠.

자 이렇게 해서 이제 Bootstrap 관련된 걸 봤고 이제 Refresh 해보면,

이렇게 나오게 됩니다.

 

다음 시간부터는 회원 등록부터 쭉 개발해보겠습니다.

'스프링 > 실전! 스프링 부트와 JPA 활용1' 카테고리의 다른 글

회원 목록 조회  (0) 2024.05.14
회원 등록  (0) 2024.05.13
주문 검색 기능 개발  (0) 2024.05.11
주문 기능 테스트  (0) 2024.05.11
주문 서비스 개발  (0) 2024.05.08