[Spring] CH12 스프링부트 컨트롤러 기본

jaegeunsong97·2023년 3월 12일
0

[Fast Campus] Spring

목록 보기
16/44
post-thumbnail

📕 1교시


먼저 레포지토리를 전부 띄운다.

따고 클래스를 두고 싱글톤으로 두는 것도 좋다. 왜냐하면 서비스가 요청될 떄마다 계속 실행이 되기 때문이다.

처음에 static으로 new를 하고 계속 재사용을 하면 되기 때문이다. 따라서 싱글톤으로 하는 것을 추천한다.

user라는 부분을 따로 받는다.

이 부분에서 왜 리퀘스트 디스페처를 사용했을까? 리다이렉트를 사용하지 않은 이유는?

web-inf에 있기때문에 접근이 안되기 때문이다. 그래서 어쩔수 없이 리퀘스트 디스페처를 사용했다.

그리고 join 부분은

다음과 같이 바꿔준다.

보면 join 요청을 하는데 try-catch로 감싸고 있다.

우리가 DS를 만들었기 떄문에

이렇게 3가지를 우리가 제어가 가능하다. 우리가 만들었기 때문에 가능하다.

Spring을 만나면 우리는 DS를 제어할 수 없다. 그래서 이부분에서는 Spring을 사용하면 어떻게 제어를 할 수 있을까? 생각을 해야한다.

따라서 지금 이부분을 기억하자

이 부분들은 우리가 제어가 가능하다! 이제 코드로 돌아가자

여기서 왜 sendRedirect를 했을까? 리다이렉트를 사용하는 이유는 우리가 이미 만든 join, joinForm etc 이런것들을 재사용할 경우에 사용한다.

즉, 엑션을 재사용을 할떄는 반드시 sendRedirect를 사용하자. 매우매우 중요하니까 외우자

회원가입은 POST 요청이다.

이렇게 되어있으면 throw 떄문에 에러가 발생하는 경우 join을 호출한 녀석한테 날라간다.

그래서 이 catch 부분에서 에러가 잡힌다.

만약 try-catch를 잡지 않으면, 하나하나 다 처리를 해줘야한다.

즉, 에러는 한 부분으로 전부 전가를 하는 것이 좋다.

오류는 제일 앞에서 try-catch로 처리하고 내부에서는 계속 throw를 하면 된다.

DS를 우리가 직접 제어를 했다.

생각을 해보자, 만약 테이블이 10개가 되면 코드가 엄청 길어진다. 따라서 리플렉션을 구현해서 하면 매우 짧게 구현이 된다.

그리고 모든 예외는 DS에서 처리를 하고 DS는 Exhandler라는 곳으로 전부 던진다.

매우 깔끔해진다.

스프링 부트 또한 이렇게 되어있다. 편해서이다.




📕 스프링


스프링 부트에서는 DS가 이미 만들어져 있다. 먼저 프레임워크의 정의를 알아보자

강제성을 부여하는 것이다.

호밀밭의 파수꾼 이야기

기본 4가지 방식의 메소드가 있다.

스크링 컨트롤러의 책임: SRP (단일 책임의 원칙) 기억하자

우리는 @ 를 붙이면 알아서 다 해주는 것이다.

RestController는 데이터를 찾아주고, Controller는 View를 리턴해준다. ViewResolver가 발동하는 것이다.

이제 실습을 해보자




📕 2교시


3점대 사용가능하지만 자바는 17이 되야한다.

코드를 작성할때마다 자동으로 컴파일을 해준다.

DS의 자동 생성

mustach는 html + JS

패키지 구조, 컨트롤러를 만들자

이렇게 어노테이션을 붙이면, 컨트롤러가 된다.

RestController는 데이터 응답 컨트롤러이다.

endpoint이다.

서버를 실행하고 Info 로그를 보자

첫번쨰 줄은 시작했다라는 것이다. 2번쨰 줄은 active profie이 설정이 되어있자 않다는 것이다.

저장시 자동 컴파일, dev-tool 알아서 동작, 서버 알아서 재시작

따라서 이제 서버 재시작 할 필요가 없다.

그리고 yaml에관해서 알아보자

yaml은 JSON의 상위집합 현존하는 가장 가벼운 것이다.

문법은 매우 간단하다

그리고 설정을 yml로 바꾸자

이 경우는 스프링 파일이 아니기 떄문에 재시작을 해주자. 그리고 dev-8080, prod-8000으로 한다.

yaml을 사용하는 이유는 중복을 제거한다.

그리고 시작을 하면

application.yml은 server.xml + web.xml 이 모두 통합된 것이다. 매우 편하다.

1번째 줄은 로깅에 관한것
2번쨰 줄은 내장 톰켓(임베디드 톰켓) 스프링은 톰켓을 들고 있다.
3번쨰 줄은 서비스를 (톰켓을) 시작하는 것
4번쨰 줄은 톰켓 버전에 관해서 말해준다. -> 톰켓 버전을 의미 -> 요즘은 단일 스레드로 변한다.(빨라서, NIO, 스레드가 놀지 않는다.)
5번쨰 줄 WebApplicationContext는 정말 중요하다. 가장 중요한 2가지가 있다.

WebApplicationContext는 -> DS를 초기화 시키고, Component scan(@이 있으면 메모리에 띄운다)을 한다.

스프링이 ComponentScan을 하면 자기 아티펙트 이하만 본다, 따라서

dd 밑에 어노테이션을 붙여도 작동하지 않는다.

정리하면, WebApplicationContext는 DS를 자동생성하고, 자기 아티펙트 이하의 @이 붙은 것들을 전부 메모리에 띄우는 역할을 하는 것이다.

Component 스캔은 스프링이 지정한 8가지 메소드를 new 시킨다.

원래 new는 DS에서 했었다. 이제 Spring이 DS를 만들기 떄문에 어노테이션을 알아서 new를 해준다.

liveReload(리스너) -> 코드 저장 -> 서버 바로 동작
컨텍스트 패스 없음
내부적으로는 while(데몬 스레드 작동 중)

이제 인터넷 창을 열어서 검색해보자

나는 잡은 적이 없는데 text/plain으로만 되어있다. 만약 내가 text/html으로 바꾸고 싶다면??

바뀌지 않는다. 제어가 안되는 것이다. 왜냐하면 Controller에서 수정을 해도 DS에서 덮어씌워지기 떄문이다. 그래서 프레임워크인 것이다.

이제 2번째는 컨트롤러에게 데이터를 전달해보자

MVC App에서 했던 requestgetParameter를 할 필요가 없다.

만약 이상태에서 키워드를 던지지 않으면 터진다.

RequestParam에 있는 것을 보고 파싱을 하는 것이다. 키워드 값을 주지않으면 null로 나온다. 기본적으로 required 라는 것이 true 라는 것이다.

3번쨰는 defaultValue를 걸 수 있다.

만역 value를 주면 다음과 같이 뜬다.

따라서 디폴트 벨류를 사용할 떄만 RequestParam을 쓰고, 그 외에는 다음과 같이 작성하면 된다.

테스트를 하면

또다른 예시

정리하면, 디폴트를 사용하고 싶으면 requestParam을 사용하고, 사용하지 않을 거면 그냥 사용하면 된다.

다음과 같이 2개를 할 수 있다. 결과는

혹시나 해서, 디폴트 값은 문자로만 받는 다 즉, int는 허용하지 않는다는 것이다. 따라서 무조건 String으로 감싸야한다.




📕 3교시


get은 바디가 없다. 일반인만 get요청을 한다.

POST 요청은 본문이 있다. body가 있고, 따라서 content type이 있다.

이번에는 RequestParam 말고 PathVariable을 사용해보자

여기서 중요한 것은 쿼리스트링과 패스베리어블은 구분할 줄 알아야한다.

결론은 PK인 id로 찾을 거면, pathVariable로 날리고, 제목 등등 이러한 PK가 아닌 겨우는 쿼리 스트링으로 날리면 된다.

예를 들어 PK가 몇번 N인 경우는 pathVariable로, 나머지는 쿼리스트링으로 날리면 된다.

구체적인 요청을 의미하는 것이다. 잘 생각해보자. 그럼 이해할 수 있다.

만약 title로 접근을 한다면, 간단하다.

이런식으로 찾는 것이다. 너무 간단하다.

구체적인 요청(get)을 할 떄이다.

다음으로 가자

여기서의 의문은 쿼리스트링인지 바디인지를 궁금해야한다. RequestParam은 2개다 파싱을 한다.

일단 주소에 먼저 보내보자

이제 param으로 보내보자

바디로 보내보자

따라서 애매하니까

다음과 같이 구분을 지어줘야한다. 바디로 보낼 것인지 아니면 주소에 실어서 보낼것인지 말이다.

쿼리스트링으로도 보낼 수 있고, x-www-form-urlencoded로도 보낼 수 있다.

이제는 Json을 던져보자

위에 처럼은 보내지 못한다. 우리는 다음과 같이 보내는 것이다.

스프링의 기본전략은 x-www-form-urlencoded이다. 따라서 전략을 변경해줘야한다.

원래 JSON 데이터를 받을 떄는 우리는 이렇게 했다.

더 이상 이렇게 할 필요가 없다. Json데이터를 받고 싶으면 다음과 같이 적으면 된다.

통신은 오브젝트로 보내지 못한다. 통신은 String으로 변경해서 보내야한다. 실행을 하면

만약 이렇게 보낸다면?

이유는 파싱 전략이 x-www 에서 @RequestBody로 바뀌었는데 올바르게 보내지 않았기 떄문이다.

즉, MimeType이 일치하지 않았기 때문이다.

이번에는 text로 보내보자

똑같다 text/plain또한 파싱하지 못한다. 이유는 전략이 변했기 때문이다.

text/pliain이 발동하려면 개념상 Buffer는 발동하고, Gson은 발동하지 않으면 된다.

RequestBody를 붙이면 버퍼가 발동을 한다. 그리고 오브젝트가 적혀있으면 Gson이 발동을 한다. 즉, 오브젝트가 없으면 Gson이 발동하지 않는다는 이야기 이다.

만약 String 으로 적는 다면?

버퍼는 발동하지만, Gson(Jackson)이 발동하지 않는다.

그대로 읽는다. 파싱을 못하는 것이다.

정리하면, RequestBody를 붙이면 파싱전략이 바뀐다. 일단 그냥 버퍼로 읽는다.

req.getParameter()를 발동시키지 않고, 내부적으로 req.getReader()를 발동시킨다.

그리고 RequestBody에 자바 오브젝트가 있으면 Jackson이 발동하고, String 으로 되어있으면 그대로 읽어버린다.

원래는 우리가 전부 구현할 수 있다.

수업 끝

profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글