본문 바로가기

국비필기노트/Spring

Spring_예제로 보는 Spring

item.zip
0.14MB

 

Point1. 데이터의 흐름(상품목록 전체 불러오기)

 

 

item.java = dto / item.repository = db 쿼리 저장 공간이라고 생각한다. 

지금 게시판은 DB가 연결되지 않은 상태로서 store에 값을 넣어 item안에서 값을 출력시키고 있는 중이다. 

 

그래서 BasicController.java에 있는 메서드가 item.repository에 있는 findAll메서드를 찾아 item이라는 변수에 값을 저장시켰고 빨간박스의 @GetMapping에 경로가 따로 없는 이유는 index.html에서 상품관리를 누르면 바로 출력되야하는 것이 전체item으로서 이미 BasicController.java의 최상단 RequestMapping에서 경로가 입력되어있기때문이다.

 

*추가설명: point5. Spring의 장점/ @Repository

https://songg5453.tistory.com/170

 

 

Point2. 경로설정방법

 

thymleaf를 통해 경로 재설정

 

웹 출력할 때 개발자는 서버를 실행해서 출력을 하고 웹 퍼블리셔는 파일을 drag&drop방법으로 끌고와 파일을 확인한다. 이때 우리는 상대경로를 사용하게 되는데 상대경로는 forward방식으로서 데이터가 흐르다가 경로가 꼬여버리는 상황이 발생한다. 그래서 개발자는 아무런 문제가 없는 파일을 공유하였는데 퍼블리셔는 어떠한 문제가 있는 파일을 받을 수 있는 경우가 있는 것이다. 

 

우리는 그래서 html파일에서 웹 퍼블리셔분들이 작성한 href의 경로말고 thymleaf를 사용하여 경로를 한번 더 입력을 해 줄 필요가 있다.

 

 

기본경로설정 

 

 

첫 시작은 초록색 박스인 index.html에서부터 시작한다. 

index.html에서 상품관리 라는  a 태그를 누르면 a href를 통해 BasicController.java로 들어가게 해두었고 이는 @RequestMapping에 의해 매핑된다. 

 

items와 addForm의 GetMapping 형태가 다른 이유는 items는 상품관리를 클릭하면 제일 처음 보여야하는 페이지로서 이미 RequestMapping에 묶여져있는 상태에 들어왔기에 ( )에 경로가 입력되어있지않는 것이다. 

그리고 return 뒤에 다음 페이지 html 경로를 입력해주어 컨트롤러를 마무리한다.

 

 

버튼 안에서의 경로설정

 

 

onclick은 웹퍼블리셔분들이 사용하는 부분이고 우리는 th:onclick을 사용하여 컨트롤러로 이동하도록 해야한다. 이 때 | Location.href='@{경로}' | 를 사용하여 컨트롤러 경로를 설정하며, 이때 경로는 빨간색과 파란색 박스를 참고하여 혼합해 작성한다.

 

 

파라미터로 구분되는 경로설정

 

 

해당 경로 역시 퍼블리셔의 정적페이지 경로에 동적페이지 경로를 thymleaf를 통해서 덮어씌워주었다.

해당 코드는 상품명을 클릭해도 회원ID로 인식하여 ID를 기준으로 상세페이지로 이동되게끔 하는 코드이다.

 

갈색 박스 th:text의 기능은 하드코딩된 회원 ID와 상품명을 특정 회원ID와 상품명으로 교체해주는 역할을 한다.  분홍박스는 경로를 의미하며 위 아래 모두 동일한 의미를 가지는 경로로서 최종적으로 밑의 경로는 위의 경로의 축약형이다. 

 

GetMapping에서 "/{넘긴파라미터}" 를 입력하여 알맞는 함수로 찾아오기 가능하며 이 때  @PathVariable 어노테이션의 사용이유는 itemId는 자동으로 sequence를 주었기때문에 파라미터를 선택적으로 넘길 필요가 없어 itemId와 model 파라미터를 각각 받도록 설정하였다.

 

 

버튼에서 파라미터 보내기

 

 

이는 item.html에서 상품수정을 누르면 해당 ID값의 상품을 찾아들어가 수정진행을 해야하기에 역시 파라미터값을 넘겨주는 작업이 필요하다. 이 때 빨간박스처럼 |  Location.href='@{경로 / 넘길파라미터}' |  형식으로 경로를 작성하며 컨트롤러에서도 이를 받아줄 땐 박스 형식을 지켜 받아오도록 처리해야만한다.

 

 

Point3. @Autowired와 @RequiredArgConstructor

두 코드 모두 BasicController.java에 있는 코드들이다.

 

빨간박스의 @Autowired가 주석처리가 된 이유:

스프링은 생성자가 하나만 있으면 스프링이 해당 생성자에게 @Autowired로 의존관계를 주입해준다. 즉, 생성자가 하나밖에 없는 경우엔 Autowired 어노테이션을 생략해 줄 수 있다. 

 

*추가설명: Spring 어노테이션

https://songg5453.tistory.com/170

 

 

남색박스의 생성자가 주석처리가 된 이유:

@RequiredArgConstructor라는 lombok에서 지원해주는 어노테이션때문이다. final키워두가 붙은 멤버변수에 한에서 사용이 가능하며 해당 어노테이션을 추가하면 생성자 주입 생략이 가능하다.

 

 

초록박스의 final:

final이라고 하는 키워드가 들어가는 방향으로 주입하는 것이 스프링에서 권고되는 방향이다. 

순환참조 혹은 nullpointexception이라는 예외상황에 있어서 스프링 주입 방법이 진화되었고 지금은 생성자 주입이 가장 권장되는 방법이다.그렇기에 한번 주입하면 변하지 않는 final 키워드를 사용을 한다.

 

*추가설명: DI의 세가지 방법

https://songg5453.tistory.com/170

 

 

Point4. 데이터출력

 

 

items.html이다. 

주황색박스에는 thymleaf를 사용하여 "상품등록"이라는 버튼을 누르면 해당 경로로 들어갈 수 있게 해주었다.

남색박스 역시 thymleaf를 사용하여 데이터를 불러오고있다.

 

*추가설명: Literals의 리터럴대체

https://songg5453.tistory.com/179

 

 

 

Point5. ModelAttribute

 

 

saveV1은 request를 하나씩 모두 받아와 item객체 만들어서 하나씩 세팅해주는 작업을 해주는 메서드이다. 이는 프론트단에서 받아오는 파라미터가 많아질수록 몹시 불편해지는 코드로서 @ModelAttribute를 사용하면 간편하게 해결할 수 있다.

 

@ModelAttribute의 역할은 1. requestParameter 정리 2. 객체생성 3. model.Attribute 작업으로서 1번으로 인해 빨간박스가 생략되었고 2번으로 인해 초록박스가 3번으로 보라색 박스가 생략이 된 것이다.

 

saveV2의 @ModelAttribute ("item")는 item이라는 객체를 선언했다고 명시적으로 나타내는 것으로 생략이 가능하여 생략해주었다. 그런데 ("item")과 item의 객체의 차이점은 뭘까?

 

주황색박스의 item을 a로 변경하였고 초록색 박스의 item을 b로 변경하였다.

 

초록박스의 item 즉, b의 역할은 프론트단에서 넘겨받은 데이터들을 b로 저장시켜주는 것이며 a는 하나의 key값으로 a라는 이름으로 데이터가 묶여서 넘어가게된다. 

 

 

그럼으로 ("aa")로 작성한다면 연결된 item.html에 aa.itemName / aa.price로 변경해야하는 것이다.

 

그런데 @ModelAttribute는 파란박스 생략이 가능하고 생략할 경우 객체 선언을 빨간박스의 a자리에서 해주어 결국 saveV2의 최종 모양이 나오게된다.

 

@ModelAttribute는 몹시 간단한 기능이지만 역시 너무 많은 생략은 혼란을 가져올 수 있기에 팀원들과의 조율이 필요하다.

 

*추가설명: 버전8

https://songg5453.tistory.com/174

 

 

Point6. redirect 형식

 

"수정" 과 "등록에 관련된 요청 페이지는 redirect 처리가 되어야한다. 

update를 forward방식으로 하게되면 기본적으로 등록 또는 수정했을 떄 전송했었던 데이터가 계속 유지되기때문에 동일 페이지에서 새로고침을 하면 계속해서 상품이 등록되는 에러가 발생하게되고 이를 위해 redirect로 사용자에게 보내는 데이터는 삭제를 해주어야 정상 처리가 된다.

 

 

현 프로젝트의 redirect 코드들이다.

RedirectAttributes 속성은 redirect시 사용되는 여러 속성을 조작해주며

basic/items/4는 url방식으로 넘어가고 status=true는 파라미터 방식으로 넘겨준다. 

 

 

*참고설명: point4.Redirect와 Forward방식

https://songg5453.tistory.com/170

 

 

 

Point7. th:action 

 

 

edit.html의 form태그의 th:action부분이다.

 

현재 form태그를 누를 때의 url은 http://localhost:9091/basic/items/2/edit 일 것이다.

이는 GET방식인데 우린 post방식으로 사용한다면 URL은 생략 가능하다.

 

즉, 같은 Url에 전송 방법만 달라지는 경우는 url을 사용하지 않아도 된다.

 

 

Point8. @PostConstruct와 @PreDestroy

 

 

지금의 예제는 DB를 사용하고 있지 않기에 서버를 끄면 저장한 데이터가 모두 삭제된다. 

그렇기에 사용하는 어노테이션 , 메서드이며 DB가 연결되어있는 상황에선 상황에 맞게 유동적이게 사용한다.

 

@PostConstrct

객체 초기화 부분이다. 

객체가 생성된 후 별도의 초기화 작업을 위해 실행해야하는 메서드를 선언한다. 

해당 어노테이션을 설정해놓은 메서드는 was가 띄워질 때 생성되며 지금 init()에서는 store라고 하는 고정 메모리 영역에다가 데이터를 put해주는 작업을 진행중이다.

 

@PreDestory

종료메서드로서 마지막 소멸단계에 스프링 컨테이너의 객체를 제거하기 전에 해야할 작업이 있다면 해당 어노테이션을 사용하여 작업한다. 

 

 

해당 어노테이션 모두 서버를 키고 끌때 사용이 되는 것에 대한 증거로 syso를 통해 console에 데이터 실행 시기를 출력시킨사진이다.