[ Spring ] Annotation 정리 (1)
스프링에서 사용하는 어노테이션 정리 - 1
Annotation | 의미 |
@SpringBootApplication | Spring boot application 으로 설정 |
@Controller | 화면(view)를 제공하는 controller로 설정 |
@RestController | Rest API를 제공하는 controller로 설정 기본적으로 respons는 objectmapper를 통해 json의 형태로 변경되어 내려간다. |
@RequestMapping | URL 주소를 맵핑 원하는 HTTP 메서드를 지정해야함. 지정하지 않을 시 모든 HTTP 메서드가 동작하게됨. |
@GetMapping | GET형식으로 요청이온 주소를 맵핑 |
@PostMapping | POST형식으로 요청이온 주소를 맵핑 |
@PutMapping | PUT(update)형식으로 요청이온 주소를 맵핑 |
@DeleteMapping | DELETE 형식으로 요청이온 주소를 맵핑 |
@RequestParam | URL Query Parameter 맵핑 |
@ModelAttribute | 객체로 파라미터를 받아서 자동 매칭이 가능하다. |
@PathVariable | URL에서 리소스 경로에서 전달 받는 변수로 {변수명} 경로 변수라고 한다. |
@RequestBody | HTTP BODY에 들어있는 내용을 Json을 오브젝트로 맵핑하려고할때 |
@Valid | POJO 자바 클래스의 검증 |
@Configration | 1개 이상의 Bean을 등록할 때 설정 |
@Component | 1개의 클래스를 Bean으로 등록 |
@Bean | 메소드를 Bean으로 생성할때 선언 |
@Autowired | DI를 사용하고 싶은 곳에 선언. |
@Qualifier | 두가지 이상의 Bean이 있을때 사용하고 싶은 Bean을 명시적으로 선언 |
@Resource | @Autowired + @Qualifier 두가지의 개념 |
@Aspect | AOP 적용시 사용 |
@Before | AOP 메소드 이전 호출되어 실행되는 내용 |
@After | AOP 메소드 호출 이후 실행되는 내용 (예외 발생포함) |
@Around | AOP 이전/이후 모두 포함 실행되는 내용 (예외 발생포함) |
@AfterReturning | AOP 메소드 호출이 정상일때 실행되는 내용 |
@AfterThrowing | AOP 해당 메소드가 예외 발생시 실행되는 내용 |
@RestController
Rest API를 제공하는 controller로 설정
기본적으로 respons는 objectmapper를 통해 json의 형태로 변경되어 내려간다.
반환 되는 String값을 클라이언트 화면의 HTML Body 에 바로 담아서 보여준다. ( @Controller의 경우 반환되는 String 값을 뷰의 이름으로 인식하여 해당 뷰를 찾아 클라이언트 화면에 전달한다. )
@RestController
public class LogTestController {
private final Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping("/log-test")
public String logTest(){
String name = "spring";
log.info("info log={}",name);
return "OK";
}
}
@Controller
- 스프링이 자동으로 스프링 빈으로 등록한다. - 내부에 @Component 어노테이션이 있어서 컴포넌트 스캔의 대상이 됨
- 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식한다. - RequestMappingHandlerMapping 에서 맵핑 정보로 인식한다. EX .@RequestMapping 또는 @Contdroller 가 클래스 레벨에 붙어 있으면 동작한다.
- ModelAndView : 모델과 뷰 정보를 담아서 반환할 수 있다.
@Controller // 빈등록되어 컴포넌트 스캔 대상 & RequestMappingHandlerMapping 맵핑 정보 전달
public class test {
@ReqestMapping("주소URI")
public ModelAndView main(){
return new ModelAndView("main");
}
}
@Component //빈등록되어 컴포넌트 스캔 대상
@RequestMapping // RequestMappingHandlerMapping 맵핑 정보 전달
public class test {
@ReqestMapping("주소URI")
public ModelAndView main(){
return new ModelAndView("main");
}
}
@RequestMapping
@RequestMapping (value="uri" , method= RequestMethod.전송방식)
URL 주소를 맵핑하는 역할을 한다. 원하는 HTTP 메서드를 지정가능하며, 따로 명시하여 지정하지 않을 시 모든 HTTP 메서드가 동작하게된다. 대채로 @GetMapping, @PostMapping... 등 명칭에서 HTTP 메서드를 지정한 어노테이션이 많이 사용된다.
- 대부분의 속성을 배열[] 로 제공하므로 다중 설정이 가능하다. {"/hello-basic", "/hello-go"}
- 뒤에 / 가 더 붙어도 동일하게 적용된다.
- "/hello-basic"
- "/hello-basic/"
@RequestMapping(value = "/new-form", method = RequestMethod.GET)
public String newForm(){
return "new-form";
}
특정 조건에 따른 매핑
특정 파라미터 조건 매핑
/**
* 파라미터로 추가 매핑
* params="mode",
* params="!mode"
* params="mode=debug"
* params="mode!=debug" (! = )
* params = {"mode=debug","data=good"}
*/
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
log.info("mappingParam");
return "ok";
}
특정 헤더 조건 매핑
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume
/**
* Content-Type 헤더 기반 추가 매핑 Media Type
* consumes="application/json"
* consumes="!application/json"
* consumes="application/*"
* consumes="*\/*"
* MediaType.APPLICATION_JSON_VALUE
*/
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
log.info("mappingConsumes");
return "ok";
}
미디어 타입 조건 매핑 - HTTP 요청 Accept, produce
/**
* Accept 헤더 기반 Media Type
* produces = "text/html"
* produces = "!text/html"
* produces = "text/*"
* produces = "*\/*"
*/
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
log.info("mappingProduces");
return "ok";
}
@PathVariable
@GetMapping("/mapping/{userId}")
- 최근 HTTP API 에서 리소스 경로에 식별자를 넣는 스타일을 선호한다.
- 변수 명이 같으면 생략이 가능하다.
- @PathVariable("userId") String data > @PathVariable String userId
- 다중 맵핑이 가능하다.
- @GetMapping("/mapping/users/{userId}/orders/{orderId}")
- @PathValiable String userId , @PathValiable Long orderId
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data){
log.info("mappingPath userId={}", data);
return "ok";
}
@RequestParam
- @RequestParam("명칭") String name
- @RequestParam String name // 명칭 동일 할 시 생략 가능
- @RequestParam(required = false) String name // required 기본 값은 true 값이 안들어와도 메서드 실행 가능
- int는 null이 들어가는 것이 불가능하다 , 받을수 있는 Integer로 데이터형을 변경하거나 defaultValue를 사용해야 한다.
- @RequestParam(required = false, defaultValue="-1") int age
- defaultValue를 사용할 경우 값이 null 또는 "" 빈문자열이 들어와도 정해진 값을 전달한다.
- @RequestParam Map<String, String> paramMap) //Map, 또는 MultivalueMap 에 넣을 수 있다.
- Map : ex ) paramMap.get("명칭")
- MultivalueMap : 파라미터 값이 동일하다면 ?username=id1&username=id2 , 일경우 MultivalueMap을 사용한다. ex)MultivalueMap(key=[value1,value2,...]) = > (key=username,value=[id1,di2])
@ResponseBody // 반환값을 BODY로 바로 전달
@RequestMapping("/request-param-required")
public String requestParamrequired(
@RequestParam(required = true) String username,
@RequestParam(required = false) Integer age
){
log.info("required - username = {} / age = {}", username,age);
return "requestParamV4 ok";
}
@ResponseBody // 반환값을 BODY로 바로 전달
@RequestMapping("/request-param-map")
public String requestParamMap(@RequestParam Map<String, String> paramMap){
log.info("default - username = {} / age = {}", paramMap.get("username"),paramMap.get("age"));
return "requestParamV4 ok";
}
@ModelAttribute
- 객채로 파라미터를 받아서 자동 매칭이 가능하다.
- 생략하고 사용이 가능하다. (argument resolver로 지정해둔 타입은 제외된다.)
[ 실행순서 ]
1) 객체 생성
2) 객체의 프로퍼티(getter,setter)를 찾는다. setter를 호출해서 파라미터 값을 바인딩
ex) 파라미터 이름이 username 이면 setUsername을 호출하여 입력하고 조회시 getUsername()이 호출 가능하다.
@ResponseBody // 반환값을 BODY로 바로 전달
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData){
log.info("ModelAttribute username ={}, age={}",helloData.getUsername(),helloData.getAge());
return "ok";
}
@RequestBody
- HTTP BODY에 들어있는 내용을 편리하게 조회할 수 있다. 참고로 헤더 정보가 필요하다면 'HttpEntity'를 사용하거나 '@RequestHeader'를 사용하면 된다.
- 생략이 불가능하다.
- Body로 전달은 @ResponseBody 어노테이션을 사용한다.
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyString4(@RequestBody String messageBody) throws IOException {
log.info("message ={}",messageBody);
return "ok";
}
HttpEntity
HttpEntity 는 Http header, body 정보를 편리하게 조회할수 있도록 한다.
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyString3(HttpEntity<String> httpEntity) throws IOException {
String entityBody = httpEntity.getBody();
log.info("message ={}",entityBody);
return new HttpEntity<>("ok");
}
메시지 바디 정보를 직접 조회가 가능하다. 요청 파라미터를 조회하는 기능과 관계가 없다.
메시지 바디 정보 직접 반환, 헤더 정보 포함 가능, View를 사용하지 않고 body에 직접 응답한다. ( RequestEntity, ResponseEntity를 사용 가능 HTTP 상태코드를 넣을 수 있다. )
@ResponseBody
응답 결과를 HTTP 메시지 바디에 직접 담아서 전달 할 수 있다. View를 사용하지 않는다.
- @ResponseStatus(HttpStatus.ok) 어노테이션을 사용해 응답 코드도 설정할 수 있다.
- 프로그램의 조건에 따라 동적으로 설정하려면 ResponsEntity를 사용하면된다.
- @Controller 를 사용했을경우 @ResponseBody를 클래스 레벨에 추가하면 클래스 내부에 들어가는 메서드 전체에 적용이 가능하다. = > @Controller + @ResponseBody = @RestController
@ModelAttribute
요청 파라미터와 전달 파리머터를 한번에 해줄 수 있다.
모델 어노테이션도 생략이 가능하다.
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item
// ,Model model //생략가능
){
Item saveItem = itemRepository.save(item);
// model.addAttribute("item",saveItem); //생략가능
return "basic/item";
}
@PostMapping("/add")
public String addItemV2(Item item){
itemRepository.save(item);
return "basic/item";
}