target
: 컴파일된 내용이 들어가는 폴더이다.- 안에 있는 내용은 컴파일을 하면서 최적화를 거친 내용들이다.
-> MvcApplication을 보면..
- 클래스 위에
@SpringBootApplication
이라는 어노테이션이 달려있다.
: 해당 클래스가 가지고 있는 'main' 메서드가 스프링 부트 웹 어플리케이션의 진입점임을 알린다.
-> 해당 어노테이션이 없다면...!
- JVM 위에서 WAR파일(웹 어플리케이션 저장소)로 만들어져서 실행이 되는데 이 사이에는 Spring Boot가 있다. @SpringBootApplication를 가진 클래스가 없다면 Spring Boot의 시작점을 찾지 못하여 오류가 발생한다.
- 수동으로 어노테이션을 추가하거나 추가되있는 걸 삭제할 일은 없음으로 역할만 알고 있으면 된다.
: 해당 클래스가 컨트롤러로 사용될 것임을 스프링 부트에게 알린다.
-> HomeController 생성
- 따로 생성하기 귀찮으니 패키지와 클래스를 함께 만드는 것을 습관들이자.
- 이렇게 만들었다고 해서
HomeController
가 컨트롤러가 되는 것이 아니라 HomeController라는 클래스에 불과하다.
- 아직 사용되지 않아서 회색을 띈다.
스프링에게 controller라는 것을 알려줘야한다.
- 회색이였던게 사용중이라는 의미인 흰색으로 바뀐 것을 볼 수 있다.
127.0.0.1
: Loopback
- ip주소이며 사용하는 본인 컴퓨터 자기 자신을 의미한다.
value : 주소, method : HTTP 메소드
: 해당 어노테이션이 클래스에 부여되면 해당 클래스가 가지는
@RequestMapping
어노테이션이 붙은 메서드의 전역적 맵핑 주소를 가지게 된다.
- 해당 어노테이션이 메서드에 부여되면 해당 메서드와 주소를 연결(맵핑)시킨다.
- 전역적 맵핑 주소는 "/" 이며 getHello() 라는 메서드가 가지는 맵핑 주소는 "hello"이다.
- 서버를 돌렸을 때 이와 같이 나와야 정상 작동을 하는 것이다.
결과적으로 맵핑 될 주소는 클래스 @RequestMapping의 value
와
메서드 @RequestMapping의 value
의 합이다.
http://127.0.0.1:8080/hello
http://127.0.0.1:8080/home/hello
맵핑된 주소가 바뀌였다면 컴파일을 해야 적용 되기 때문에 서버를 꼭 다시 돌려야한다.
❗️ 메서드 안에서 home이라는 언급은 어디에도 없는데
/home~
이런식으로 맵핑이 된다. 그 이유는 해당 메서드를 가진 클래스에@RequestMapping
이 붙어서 전역적으로 작동을 하기 떄문에 명시를 하지 않아도 맵핑이 된다.
루트(/
)를 맵핑하는 컨트롤러의 이름은 보통 HomeControlelr 혹은 RootController
로 지정하며 홈 또는 루트 컨트롤러 클래스에 붙은 RequestMapping은 /
로 지정을 한다.
: 요청에 대한 맵핑을 어떻게 걸어야 하는가에 대한 관례
- 특별한 경우가 아니면 맵핑은
/{대상}/{동작}
구조로 이루어진다.가령 회원 - 로그인 : /user/login 게시글 - 작성 : /article/write
대상 : 클래스 맵핑 동작 : 메서드 맵핑
- 위 <1>에서 사용한
{대상}
은 컨트롤러의 맵핑이고,{동작}
은 메서드의 맵핑이다.가령 회원 - 로그인 (/user/login) 같은 경우는 '/user' 로 전역 맵핑된 'UserController' 클래스 내의 'login'으로 맵핑된 메서드
- 단,
{대상}
이 생략되고{동작}
으로만 맵핑이 걸려야한다면 이는/(root)
로 전역 맵핑된HomeController
클래스를 사용한다.
http://127.0.0.1:8080
이와 같이대상 / 동작
이 모두 생략된 경우에는HomeController
클래스 사용
{동작}
에 대한 메서드 이름은{HTTP 메서드}{동작}
으로 이루어진다.가령 회원 - 로그인 같은 경우는 '/user' 로 맵핑된 'UserController' 클래스 내에 '/'로 맵핑된 getLogin(...), postLogin(...) 등의 이름을 활용한다.
단,
{동작}
이 생략된 경우 메서드 맵핑을/
로 한다.가령 '{대상}' 과 '{동작}'이 모두 생략될 경우 '/'로 전역 맵핑된 HomeController 클래스 내에 '/'로 맵핑된 getIndex(...), postIndex(...) 등의 이름을 활용한다.
RequestMapping은 둘 다 "/"가 되는 경우는 HomeController에서 ~Index메서드가 있을 때만 존재한다!
http://127.0.0.1:8080
{동작}이 생략되었을 경우 HomeController에서 일을 해야되는 것이고,
{대상}과 {동작}이 생략되었을 경우 ~Index라는 메서드를 만들어야하며 RequestMapping은 둘다 "/"가 된다.
- 구글의 HomeController getIndex에 만든 페이지다. (의미만 생각)
- 대부분 이런식으로 개발을 한다.
index : 어떤 디렉터리 안에있는 색인 = 목차 정도를 의미한다.
옛날에는 해당 디렉터리의 모든 파일을 보여주는 것을 index page라고 칭했다.
- 해당 디렉터리에 어떤 파일과 어떤 규칙이 있는가에 대해 나타내는 것
현재는 그 디렉터리의 첫 페이지를 index page 라고 한다.
웹 페이지를 만들기 위해 html코드를 작성해야하는데 아래와 같이 return에 다 작성을 할 수가 없다.
그렇기 떄문에! HomeController와 연결된 html파일을 만들어보자.
resources -> templates
컨트롤러이름/메서드이름.html
로 생성
- 이 주소로 들어오면 이 파일이 뜨게하기 위해서 return 하는 값을 "home/index" 로 설정했다. index뒤에 html은 알아서 붙여주기 때문에 명시하지 않아도 괜찮다.
- 예상했던 결과다. index.html 파일이 뜨지 않는다.
지금까지 어떠한 내용을 화면에 찍기위해서 return에 값을 썼었다.
그때처럼 지금도 return의 값이 찍힐 뿐이다.
그 이유는 @Responsbody의 역할 때문인데 한번 지워보자.
- @Responsbody 어노테이션을 없애니 html파일이 잘 불러와진다.
- 이전에는 return값이 문자열 처럼 작동을 했지만 어노테이션이을 없애자마자 밑줄이 생기고 command 누르고 index를 누르게 되면 html파일이 열리게 된다.
: 해당 메서드가 반환할 값이 Thymeleaf 템플릿이 아닌, 값 그 자체로 반환되어야함을 알린다.
@ResponseBody
을 붙이고 return "home/index";
을 하면
문자열 값 그 자체가 응답으로 들어가게 된다.
반대로 @ResponseBody
을 붙이지 않고 return "home/index";
을 하면
~/templates/home/index.html
을 찾아간다.
-> ~/templates
와 html
은 자동으로 붙여준다.
왜 자동으로 붙여줄까?
Application Properties에서 확인을 해보자.
- 명시를 해주지 않으면 이 값이 자동적으로 써진다.
(바꿀 수 있긴한데 바꿀필요가 없다.)prefix : classpath:/templates/ suffix : .html
- 수정은 이렇게 하면되고 이렇게 설정하게되면
.txt
로 끝나는 파일을 찾게 된다.
server.port
: 톰 캣 웹 서버가 돌아갈 포트(기본값 : 8080)
spring.thymeleaf.prefix
: Thymeleaf 템플릿 경로 앞에 붙일 접두어(기본값 : classpath:templates/)
spring.thymeleaf.suffix
: Thymeleaf 템플릿 경로 뒤에 붙일 접미어(기본값 : .html)
- html에서 간단하게 계산기를 만들었다.
method = RequestMethod.GET
을 적어줘야 비로소 HomeController가 GET맵핑이 된 것이다.method = HTTP 메서드 // 작성 형식
- form에 method 속성을 post값으로 준다.
이렇게 작성을 했을 때 사이트는 잘 뜬다. 그런데 submit을 하게 되면 바로 오류가 생긴다.
- submit을 하면 405 오류가 뜬다.
- 이 창은 get이 아니라 post로 들어갔다.
주소를 찍고 해당 페이지로 들어가는 것은 요청 값이 GET이고 GET에 대한 맵핑은 잘되어있다.
submit을 하게 되면 주소는 똑같지만 요청이 get이 아니라 post로 들어갔다.
- 상태 코드(Status Code)
- 200 : OK
- 400 : NOT FOUND , 존재하지 않는 경로 (정적 리소스 및 맵핑 없음)
- 405 : Method Not Allowed, 주소는 존재하는데 요청 방식(Method)을 지원하지 않음
- 500 : Internal Server Error, 서버 오류 (인텔리제이 확인)
- 주소
- 절대 경로 (Absolute Path) :
/
로 시작하는 경로 혹은 도메인으로 시작하는 경로- 상대 경로 (RelativePath) : 디렉토리 이름 혹은 파일 이름으로 시작하는 경로 (
/
나 도메인으로 시작하지 않음)- 절대경로 탐색시 현재 도메인의 루트 디렉토리부터 탐색하며 상대 경로 탐색시 현재 위치한 디렉토리를 기준으로 이동한다.
현재 `http://localhost:8080/user/login` 이라는 경로를 탐색 중이고
해당 페이지에서 href가 `register` 인 링크를 클릭하면
`http://localhost:8080/user/register`로 이동한다.
하지만, href 가 `/register` 인 링크를 클릭하면
`http://localhost:8080/register` 로 이동한다.
http://localhost:8080/user/login
에서
<a href="register>회원가입 </a>
클릭시http://localhost:8080/user/register
로 이동
http://localhost:8080/user/login
에서
<a href="/register>회원가입 </a>
클릭시http://localhost:8080/register
로 이동
주소 치고 들어가는 것 : GET
현재 POST에 대한 맵핑이 없어서 submit을 하게 되면 405 오류가 발생했던 것이다. (form에 post요청으로 적었기 때문)
html의 form태그에 method를 GET으로 변경하면 작동은 되지만 주소창에 submit하는 값이 계속해서 찍히게 된다.
- POST 맵핑
http://127.0.0.1:8080
그냥 주소 찍고 들어가면 (enter) GET 요청이 뜬다.
- 계산 및 submit을 계속하면 POST 요청이 뜨게 된다.
지금으로써 주소을 쳐서 POST 요청으로 들어갈 방법은 없다.
: 동일한 주소에 대해 요청 방식(Method)을 달리하여 서로 다른 로직을 구현하는 것 혹은 그러한 방식
- 지금 적은 HomeController은 맵핑 자체만 봤을 때 Restful이다.
name : 변수 이름, (input name 과 동일 ) required : 해당 변수를 가져올 수 없을 경우 기본 값을 사용한다면 false, 오류를 발생시켜야 한다면 true로 지정
: 요청(Request)에 있는 변수를 가져온다.
- 매개변수 자리에 작성한다.
- 이렇게 매개변수 하나이다.
요청에서 가져와야하기때문에 @RequestParam을 적어주는 것이다.
❗️ 여기서 중요한점
html에서 input의 name
과 RequestParam의 name
이 일치해야한다.
그래야 input에 적어논 값들이 각각의 변수에 들어갈 수 있게 된다.
뒤에 변수의 이름과는 무관하다. 변수에는 값만 들어갈 뿐이다.
눈으로 확인해보자면 ->
- 여기 name이 같은 input의 값들이
- @RequestParam의 name과 같은 곳의 변수로 들어간다. (얘네는 변수)
- 웹에서 작성한 input들이 sout되는 것을 확인할 수 있다.
- ❗️ case문을 사용하려면 option태그의
value
를 작성해야한다
- 만약
return String.valueOf(result);
에서
result = 7.0
이라면 돌려주는 값은classpath:/templates/7.0.html
이 되버려서 해당 파일을 찾을 수 없으니 오류가 뜬다.
응답값 그 자체를 결과로 돌려줘야한다. => @ResponsBody
- 결과가 화면에 찍히게 된다.