웹 개발 Spring Day2 어노테이션(Annotation), GET / POST 요청 , HTTP

김지원·2022년 7월 26일
0

WebDevelop2

목록 보기
21/34

  • target : 컴파일된 내용이 들어가는 폴더이다.
  • 안에 있는 내용은 컴파일을 하면서 최적화를 거친 내용들이다.

-> MvcApplication을 보면..

  • 클래스 위에 @SpringBootApplication 이라는 어노테이션이 달려있다.

어노테이션(Annotation)

@SpringBootApplication {Class}

: 해당 클래스가 가지고 있는 'main' 메서드가 스프링 부트 웹 어플리케이션의 진입점임을 알린다.

-> 해당 어노테이션이 없다면...!

  • JVM 위에서 WAR파일(웹 어플리케이션 저장소)로 만들어져서 실행이 되는데 이 사이에는 Spring Boot가 있다. @SpringBootApplication를 가진 클래스가 없다면 Spring Boot의 시작점을 찾지 못하여 오류가 발생한다.
  • 수동으로 어노테이션을 추가하거나 추가되있는 걸 삭제할 일은 없음으로 역할만 알고 있으면 된다.

@Controller {Class}

: 해당 클래스가 컨트롤러로 사용될 것임을 스프링 부트에게 알린다.

-> HomeController 생성

  • 따로 생성하기 귀찮으니 패키지와 클래스를 함께 만드는 것을 습관들이자.
  • 이렇게 만들었다고 해서 HomeController가 컨트롤러가 되는 것이 아니라 HomeController라는 클래스에 불과하다.
  • 아직 사용되지 않아서 회색을 띈다.

스프링에게 controller라는 것을 알려줘야한다.

  • 회색이였던게 사용중이라는 의미인 흰색으로 바뀐 것을 볼 수 있다.

127.0.0.1 : Loopback

  • ip주소이며 사용하는 본인 컴퓨터 자기 자신을 의미한다.

@RequestMapping {Class | Method}

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은 /로 지정을 한다.


Request Mapping Convention

: 요청에 대한 맵핑을 어떻게 걸어야 하는가에 대한 관례

  1. 특별한 경우가 아니면 맵핑은 /{대상}/{동작} 구조로 이루어진다.
가령 회원  - 로그인 : /user/login
    게시글 - 작성  : /article/write
대상 : 클래스 맵핑
동작 : 메서드 맵핑
  1. 위 <1>에서 사용한 {대상}은 컨트롤러의 맵핑이고, {동작}은 메서드의 맵핑이다.
가령 회원 - 로그인 (/user/login) 같은 경우는 
'/user' 로 전역 맵핑된 'UserController' 클래스 내의 'login'으로 맵핑된 메서드 
  1. 단, {대상}이 생략되고 {동작}으로만 맵핑이 걸려야한다면 이는 /(root)로 전역 맵핑된 HomeController 클래스를 사용한다.
  • http://127.0.0.1:8080 이와 같이 대상 / 동작 이 모두 생략된 경우에는 HomeController 클래스 사용
  1. {동작}에 대한 메서드 이름은 {HTTP 메서드}{동작}으로 이루어진다.
가령 회원 - 로그인 같은 경우는 
'/user' 로 맵핑된 'UserController' 클래스 내에 '/'로 
맵핑된 getLogin(...), postLogin(...) 등의 이름을 활용한다.

단, {동작}이 생략된 경우 메서드 맵핑을 /로 한다.

가령 '{대상}' 과 '{동작}'이 모두 생략될 경우 
'/'로 전역 맵핑된 HomeController 클래스 내에 '/'로 맵핑된 
getIndex(...), postIndex(...) 등의 이름을 활용한다. 

RequestMapping은 둘 다 "/"가 되는 경우는 HomeController에서 ~Index메서드가 있을 때만 존재한다!

  • http://127.0.0.1:8080

{동작}이 생략되었을 경우 HomeController에서 일을 해야되는 것이고,
{대상}과 {동작}이 생략되었을 경우 ~Index라는 메서드를 만들어야하며 RequestMapping은 둘다 "/"가 된다.

index page : root 디렉터리에 대한 색인 페이지

  • 구글의 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파일이 열리게 된다.

@ResponseBody {Method}

: 해당 메서드가 반환할 값이 Thymeleaf 템플릿이 아닌, 값 그 자체로 반환되어야함을 알린다.

@ResponseBody을 붙이고 return "home/index"; 을 하면
문자열 값 그 자체가 응답으로 들어가게 된다.

반대로 @ResponseBody을 붙이지 않고 return "home/index";을 하면
~/templates/home/index.html 을 찾아간다.
-> ~/templateshtml 은 자동으로 붙여준다.


왜 자동으로 붙여줄까?
Application Properties에서 확인을 해보자.

  • 명시를 해주지 않으면 이 값이 자동적으로 써진다.
    (바꿀 수 있긴한데 바꿀필요가 없다.)
prefix : classpath:/templates/
suffix : .html

  • 수정은 이렇게 하면되고 이렇게 설정하게되면 .txt로 끝나는 파일을 찾게 된다.

Application Properties

server.port

: 톰 캣 웹 서버가 돌아갈 포트(기본값 : 8080)

spring.thymeleaf.prefix

: Thymeleaf 템플릿 경로 앞에 붙일 접두어(기본값 : classpath:templates/)

spring.thymeleaf.suffix

: Thymeleaf 템플릿 경로 뒤에 붙일 접미어(기본값 : .html)


요청 방식 : GET, POST

  • html에서 간단하게 계산기를 만들었다.

주소창에 주소 치는 것 : GET 요청

  • method = RequestMethod.GET을 적어줘야 비로소 HomeController가 GET맵핑이 된 것이다.
method = HTTP 메서드  // 작성 형식

html / method = post

  • form에 method 속성을 post값으로 준다.

이렇게 작성을 했을 때 사이트는 잘 뜬다. 그런데 submit을 하게 되면 바로 오류가 생긴다.

  • submit을 하면 405 오류가 뜬다.
  • 이 창은 get이 아니라 post로 들어갔다.
    주소를 찍고 해당 페이지로 들어가는 것은 요청 값이 GET이고 GET에 대한 맵핑은 잘되어있다.
    submit을 하게 되면 주소는 똑같지만 요청이 get이 아니라 post로 들어갔다.

HTTP

  1. 상태 코드(Status Code)
  • 200 : OK
  • 400 : NOT FOUND , 존재하지 않는 경로 (정적 리소스 및 맵핑 없음)
  • 405 : Method Not Allowed, 주소는 존재하는데 요청 방식(Method)을 지원하지 않음
  • 500 : Internal Server Error, 서버 오류 (인텔리제이 확인)
  1. 주소
  • 절대 경로 (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 로 이동


POST 요청

주소 치고 들어가는 것 : GET
현재 POST에 대한 맵핑이 없어서 submit을 하게 되면 405 오류가 발생했던 것이다. (form에 post요청으로 적었기 때문)

html의 form태그에 method를 GET으로 변경하면 작동은 되지만 주소창에 submit하는 값이 계속해서 찍히게 된다.

  • POST 맵핑

  • http://127.0.0.1:8080 그냥 주소 찍고 들어가면 (enter) GET 요청이 뜬다.

  • 계산 및 submit을 계속하면 POST 요청이 뜨게 된다.

지금으로써 주소을 쳐서 POST 요청으로 들어갈 방법은 없다.


Restful

: 동일한 주소에 대해 요청 방식(Method)을 달리하여 서로 다른 로직을 구현하는 것 혹은 그러한 방식

  • 지금 적은 HomeController은 맵핑 자체만 봤을 때 Restful이다.

@RequestParam {Variable}

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

  • 결과가 화면에 찍히게 된다.
profile
Software Developer : -)

0개의 댓글