localhost:8080 으로 접속했을시
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat May 27 06:30:50 KST 2023
There was an unexpected error (type=Not Found, status=404).
라는 메세지를 보았었다.
해석해보면
이 응용 프로그램에는 /error에 대한 명시적 매핑이 없으므로 대체 항목으로 표시됩니다.
기본 url 인 "/" 에 mapping 된 값이 없어 error 페이지가 나온것이다.
package com.hello.hello.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/")
public String home() {
return "Hello World!";
}
@GetMapping("/hello")
public String hello() {
return "Hello";
}
}
controller directory 를 만들고 HelloController 클래스를 만들었다.
"/" 으로 접속시 "Hello World!" 를 반환
"/hello" 으로 접속시 "Hello" 를 반환하려고 한다.
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;
/**
* A convenience annotation that is itself annotated with
* {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
* <p>
* Types that carry this annotation are treated as controllers where
* {@link RequestMapping @RequestMapping} methods assume
* {@link ResponseBody @ResponseBody} semantics by default.
*
* <p><b>NOTE:</b> {@code @RestController} is processed if an appropriate
* {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
* {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
* pair which are the default in the MVC Java config and the MVC namespace.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
@RestController 어노테이션 을 살펴보자
@Controller 어노테이션과 @ResponseBody 어노테이션이 붙어있다.
컨트롤러 이면서 클라이언트 요청에 의해 반환될 Model 이 Body 에 직접 보여진다는 의미이다.
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.stereotype;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Indicates that an annotated class is a "Controller" (e.g. a web controller).
*
* <p>This annotation serves as a specialization of {@link Component @Component},
* allowing for implementation classes to be autodetected through classpath scanning.
* It is typically used in combination with annotated handler methods based on the
* {@link org.springframework.web.bind.annotation.RequestMapping} annotation.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 2.5
* @see Component
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller 에는 @Component 어노테이션이 포함되어있으며
@Component 어노테이션은 스프링 컨테이너에 빈 등록하는법 에서 알아봤듯이 스프링 컨테이너에 빈을 등록해준다.
정리해보면 @Component 를 포함하는 @Controller 를 포함하는 @RestController 는 스프링 컨테이너에 빈으로 등록되었다.
@ResponseBody 어노테이션은 자바 객체를 HttpResponse 의 본문인 responseBody 의 내용으로 매핑하는 역할을 한다.
@RestController 는
@Controller (@Component) 어노테이션에 의해 컴포넌트 스캔 방식에 의해 스프링 컨테이너에 빈으로 등록되어지며
@ResponseBody 어노테이션에 의해 반환 데이터를 ResponseBody 에 담아 전송한다.
"/" 로 접속을 했더니 화면에 우리가 반환한 Hello World! 가 보인다.
이번엔 "/hello" 로 접속해보자.
우리가 컨트롤러 에서 반환하려고한 Hello 가 보인다.
이처럼 컨트롤러 에서는 요청에 따른 Model 을 만들고 ModelAndView 타입을 반환하여
이를 화면에 보여준다.
정리해보면 Controller 의 역할은 사용자의 요청을 받아 처리한후 지정된 뷰에 모델 객체를 넘겨주는 역할이다.