출처: https://hbase.tistory.com/169
https://gosu-developer.tistory.com/22
어노테이션 이란?사전적 의미는 주석이지만 소스코드에 추가해서 사용할 수 있는 메타 데이터의 일종. 즉, 애플리케이션이 처리해야할 데이터가 아닌(프로그래밍 언어에 영향을 미치지 않음) 컴파일,빌드, 런타임 과정에서 코드를 어떻게 처리해야하는지를 알려주기 위한 추가 정보
에너테이션 범위에 있는 코드는 에너테이션이 의미를 갖는 특정 프로그램에서만 유효함. 다른 프로그램 한테는 영향을 미
치지 않음. 자바 문법 자체를 바꿀 필요도 없고 특정 프로그램 한테만 정보(ex. 설정정보)를 제공하는 것임.
자바의 어노테이션은 소스코드에 추가해서 사용할 수 있는 메타 데이터의 일종. 메타 데이터란 애플리케이션이 처리해야할 데이터가 아니라 컴파일 과정과 실행 과정에서 코드를 어떻게 처리해야하는지를 알려주기 위한 추가 정보이다(즉 어노테이션은 항상 컴파일러라는 프로그램을 거치고 경우에 따라 서버나 Junit과 같은 다른 프로그램에게 정보를 전달한다.
햇갈리지 말것이 메타 데이터와 메타 어노테이션을 햇갈리지 말자. 메타 데이터가 메타 어노테이션보다 포괄적인 의미 같음. 메타 데이터가 코드를 어떻게 처리해야 할지 컴파일러에게 알려주는 데이터라면 메타 어노테이션은 어노테이션을 위한 어노테이션의 의미.
나는 여태껏 아래와 같은 컴파일러에게 정보를 전달하는 에너테이션만 공부해와서 이렇게 서버에 날리는 에너테이션이 익숙치 않은 것이다..
에너테이션은 함수에 붙을 수도, 클래스에 붙을 수도, 인터페이스에 붙을 수도 있다. (글 하단에 메타 에너테이션의 하나인 @Target 에너테이션이 있다. 에너테이션의 적용대상을 지정하는 에너테이션으로 에너테이션은 클래스, 필드, 메서드, 인터페이스 등등 오만곳에 다 붙을 수 있다.) 에너테이션을 적용하고자 하는 곳 바로 위에 붙여준다.
어노테이션은 소괄호안에 해당 어노테이션과 연관된 정보가 올수 있다. GetMapping이란 어노테이션안에 무엇을 무엇과 Mapping시킬 것이지 그 정보를 알려 주는 것처럼.
참고. @SuppressWarnings ==>> 내가 해당 경고를 이미 인지하고 있음을 컴파일러에게 알리는 의미가 있음.
ArrayList는 저네릭 클래스로 저네릭 타입을 지정해 주어야 한다(<T>) 하지만 위의 예에서는 지정해 주지 않았으므로 보통의 경우에는 컴파일러가 경고 메시지를 띄우게 된다. 하지만 내가 일부러 저네릭 타입을 지정해 주지 않았다는 것을 컴파일러에게 알리고자 할때 @SuppressWarnings라는 어노테이션을 붙이게 된다.
정리:
상속, 인터페이스 방식을 대신하는 어노테이션(@)
전송방식(ex. GET, POST)에 대한 처리를 어노테이션만을 이용하여 처리할 수 있음.
@Controller 후 클래스생성하고 그 아래 메서드들을 정의 함으로다양한 타입의 파라미터처리, 다양한 타입의 리턴타입을 사용할 수 있다.
(내생각)url을 통해 클라이언트로부터 전달받은 요청을 서버내의 소스파일변경 없이(HttpServletRequest, HttpServletResponse) 어떻게 처리할지 단순히 Controller 내에 함수를 하나 정의 함으로써 처리할 수 있음.
출처 : http://kyd5083.blogspot.com/2013/04/spring-mvc.html
Controller는 스프링 MVC에서 서버분의 거의 대부분을 컨트롤 하는 부분이다.
스프링 Controller는 Client로부터 받은 요청을 어떻게 처리할지에 대한 정보들이 담겨있다.
예를들어 URL을 통해 페이지를 옮겨준다던지 모델과 연결하여 데이터베이스에 필요한 정보를 요청한다던지 하는 역할을 한다.
스프링MVC Controller의 특징을 보자
- HttpServletRequest, HttpServletResponse를 거의 사용하지 않고 필요한 기능 구현 가능하다.
- 다양한 타입의 파라미터처리, 다양한 타입의 리턴타입을 사용할 수 있다.
- GET방식, POST방식 등 전송 방식에 대한 처리를 어노테이션을 이용하여 처리할 수 있다.
- 상속/인터페이스 방식 대신에 어노테이션만으로도 필요한 설정을 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Controller
@RequestMapping("/sample/*")
@Log4j
public class SampleController {
@RequestMapping(value= "/basic",method = {RequestMethod.GET, RequestMethod.POST})
public void basicGet(){
log.info("basic..........................");
}
@GetMapping("/basicOnlyGet")
public void basicGet2(){
log.info("basic get only get...........");
}
@GetMapping("/ex01")
public String ex01(SampleDTO dto){
log.info(" "+ dto);
return "ex01";
}
|
cs |
- @Controller 어노테이션을 통해 Controller라는 것을 알려준다.
- @RequestMapping("/sample/*")
- sample/ 뒤에 들어가는 모든 것들을 이 컨트롤러에서 처리하겠다는 표시이다.
@RequestMapping(value = "/basic", method ={RequestMethod.GET/, RequestMethod.POST}
위 어노테이션은 /basic의 링크로 GET방식과 POST방식으로 통신하겠다는 뜻이다.
@GetMapping("/basic")
@PostMapping("/basic")
둘을 나누어서 쓰는것도 가능하다.
우선 Controller가 작동하기 위해서는 스프링 컨테이너에 Bean으로 등록이 되어야 하는데 ServletConfig.java파일에 Controller 클래스 파일의 위치를 추가하여 스프링 컨테이너가 빈을 생성할 수 있도록 설정해 주어야 한다.
ServletConfig.java(아.. 이제 좀 명확히 이해가 된다. 어노테이션이라는 것이 다른 프로그램에 정보를 주기위한 목적이므로 Controller라는 서버와 관련된 어노테이션은 스프링 컨테이너에 Controller가 bean으로 등록되어 있어야 한다는 말이다. 그래야지 서버로 정보를 전달했을때 서버가 이를 처리할 수 있으니 말이다)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package org.onett.config;
@EnableWebMvc
@ComponentScan(basePackages = {"org.onett.controller"})
public class ServletConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
registry.viewResolver(bean);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
|
cs |
파라미터의 수집과 변환
@RequestParam("") 의 파라미터는 브라우저에서 요청하는 변수의 이름이다.
String name은 컨트롤러 내부에서 사용할 변수의 이름이다.
일반적으로 @RequestParam을 하지 않는다면 같은 변수의 이름에 값이 할당된다.
1
2
3
4
5
6
7
8
|
@GetMapping("/ex02")
public String ex02(@RequestParam("name") String name, @RequestParam("age") int age){
log.info("name : " + name);
log.info("age : " + age);
return "ex02";
}
|
cs |
브라우저 : https://localhost:8080/sample/ex02?name=AAA&age=10
1
2
3
4
5
6
7
|
@GetMapping("/ex02List")
public String ex02(@RequestParam("ids") ArrayList<String> ids){
log.info("ids : " + ids);
return "ex02List";
}
|
cs |
브라우저 : http://localhost:8181/sample/ex02List?ids=AAA&ids=123&ids=sakjdla
1
2
3
4
5
|
@GetMapping("/ex03")
public String ex03(TodoDTO dto){
log.info(dto);
return "ex03";
}
|
cs |
브라우저 : http://localhost:8181/sample/ex03?title=ajdklf&dueDate=2020/12/11
TodoDTO객체를 만들어서 객체를 파라미터로 받을 수 있다. get으로 요청할때 DTO객체 내부 변수의 이름과 GET으로 요청하는 변수의 이름이 같아야 된다.
위와같이 날짜를 출력하기 위해서는 데이터를 바인드 해야한다.
TodoDTO.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package org.onett.domain;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class TodoDTO {
private String title;
@DateTimeFormat(pattern = "yyyy/MM/dd")
private Date dueDate;
}
|
cs |
@DataTimeFormat 어노테이션을 이용하여 Date 객체를 바인드 한다.
데이터 전달자 Model
Model을 사용하는 경우는 주로 Controller에 전달된 데이터를 이요해서 추가적인 데이터를 가져와야 하는 상황에 이용한다.(ex_ client로부터 받은 정보를 가공하여 다시 view로 전달해 줄때)
1
2
3
4
5
6
|
@GetMapping("/ex04")
public String ex04(SampleDTO dto, @ModelAttribute("page") int page){
log.info(dto);
log.info(page);
return "/sample/ex04";
}
|
cs |
위 코드는 /sample/ex04로 데이터를 전달해 준다.
SampleDTO는 ModelAttribute에 담아서 전달하지 않아도 이미 스프링 컨테이너에 bean으로 등록 되어 있기 때문에 jsp파일에서 이용할 수 있다. 하지만 int page 변수는 Model객체에 담아서 jsp로 전달해 주어야 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
Hellow world!!
<h1>${sampleDTO}</h1>
<h1>page = ${page}</h1>
</body>
</html>
|
cs |
sample/ex04.jsp
@ResponseBody
1
2
3
4
5
|
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
|
cs |
dependency를 추가해 준다.
1
2
3
4
5
6
7
8
9
|
@GetMapping("/ex06")
public @ResponseBody SampleDTO ex06(){
log.info("/ex06....................");
SampleDTO dto = new SampleDTO();
dto.setAge(10);
dto.setName("sex");
return dto;
}
|
cs |
@ResponseBody의 역할은 return 값을 JSON데이터로 바인딩하여 전달해 주는 역할을 한다.
브라우저 : http://localhost:8181/sample/ex06?name=dqw&age=123
@ResponseEntity
ResponseBody와 비슷하지만 HttpHeader를 이용해서 추가적인 정보를 전달할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
|
@GetMapping("/ex07")
public ResponseEntity<String> ex07(){
log.info("/ex07................");
String msg = "{\"name\" : \"홍길동\"}";
HttpHeaders header = new HttpHeaders();
header.add("Content-Type", "application/json;charset=UTF-8");
return new ResponseEntity<>(msg, header, HttpStatus.OK);
}
|
cs |
브라우저 : http://localhost/sample/ex07
HttpHeaders header 에 대한 정보다 같이 잘 전달된 것을 확인할 수 있다.
TYPE_USE : 참조 변수를 말함
위에서 보는바와 같이 에너테이션을 적용할때 추상메서드를 지정하고 있다. 또한 적용할 때는 메서드의 이름과 타입에 맞게 위처럼 지정해 주면 된다. 또한 어노테이션의 추상 메서드는 구현해 줄 필요가 없습니다. 그냥 위와 같이 정의하고 적용하면 끝입니다. 이름과 타입을 맞추어 주므로 순서는 상관없습니다.
이렇게 하면 어노테이션을 통해 정보를 얻는 프로그램은 해당 어노테이션을 가리키는 참조 변수가 있고 그 변수를 통해 값을 얻게 되는 것입니다. 예를들어 anno라는 참조변수가 위 빨간박스의 TestInfo 어노테이션을 가리키는 참조 변수라면 anno.count()를 통해 3이라는 값을 얻는 것입니다.
(우리는 주로 빨간박스안에서 처럼 어노테이션을 사용하는 입장이지 어노테이션으로부터 정보를 얻는 프로그램을 접하는 일은 없을 것입니다. 다만 그러한 프로그램이 anno.count()를 통해 그 값을 얻는다고 알고 있으면 됩니다.)
요소가 하나도 정의되지 않았으니 아래와 같이 실제로 쓰일때에도 그냥 요소없이 어노테이션만 오면 되는 것이다!!
'Spring&IntelliJ' 카테고리의 다른 글
MyBatis란? (0) | 2023.10.24 |
---|---|
JPA란? (0) | 2023.10.22 |
템플릿 엔진? thymeleaf템플릿 엔진이란? JSP와 servlet의 다른점? (0) | 2023.09.30 |
controller의 메서드의 매개변수로 오는 model객체란? (0) | 2023.09.30 |
디스패처 서블릿(Dispatcher servlet), Intercept, (0) | 2023.09.29 |