package com.minsung.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.log4j.Log4j;
@Controller
@RequestMapping("/sample/*")
@Log4j
public class SampleController {
@RequestMapping("")
public void basic() {
log.info("basic");
}
}
Spring MVC는 어노테이션을 중심으로 구성이 된다. = 어노테이션 잘 알아야 한다.
@Controller : 이 클래스가 Controller라고 알리는 것이다. 이게 써진 클래스는 자동으로 스프링의 객체(Bean)으로 등록된다.
servlet-context.xml에 지정된 패키지를 스캔하도록 설정되어 있음.
<context:component-scan base-package="com.minsung.controller" />
@RequestMapping : 클래스의 선언부 / 메서드의 선언부 둘다 사용이 가능하다.
클래스 선언부에 작성되면 현재 클래스의 모든 메서드들의 기본적인 URL 경로
메서드 선언부에 작성되면 클래스 선언부에 작성된 주소 뒤에 추가적으로 붙는 경로를 설정할 수 있다.
@Log4j : @Log는 java.util.Logging을 이용, 얘는 Log4j라이브러리를 활용
Spring Legacy Project로 생성한 프로젝트는 기본적으로 Log4j설정이 되어있으므로 별도의 설정이 필요하지 않다.
⚠ @Log4j에 에러가 뜬다면 pom.xml의 log4j scope 부분을 주석처리해보자.
RequestMapping은 몇가지 속성을 추가할 수 있다. 자주 사용되는것이 method속성이다. get,post방식을 구분하여 지정할 수 있다.
여기서 추가된게 @GetMapping, @PostMapping 이다.
@RequestMapping(value="/basic", method= {RequestMethod.GET, RequestMethod.POST})
public void basicGet() {
}
@GetMapping("/basicOnlyGet")
public void basicGet2() {
}
@RequestMapping은 GET, POST 방식 모두를 지원하려면 배열 형태로 처리해주면 된다.
@GetMapping같은 것은 오로지 그 방식에만 사용이 가능하므로 PUT, DELETE 방식등을 처리할 수 없다.
Spring MVC에서 Controller의 가장 편리한 기능 중 하나는 파라미터를 자동으로 (또한 매우 강력하게) 수집해준다는 것이다.
기존 JSP, Servlet으로 프로그래밍을 할 때처럼 request.getParameter()
을 사용하지 않아도 된다.
package com.minsung.domain;
import lombok.Data;
@Data
public class SampleDTO {
private String name;
private int age;
}
예제를 위한 DTO클래스.
@Data를 사용하여 getter/setter, 생성자, toString()등을 자동 생성하였다.
SampleController에 다음 메서드를 추가해보자.
@GetMapping("/ex01")
public String ex01(SampleDTO dto) {
log.info("" + dto);
return "ex01";
}
프로젝트를 실행시킨 후 브라우저 주소창에 다음과 같이 입력해보면
http://localhost:8181/controller/sample/ex01?name=kang&age=11
서버측 로그에
INFO : com.minsung.controller.SampleController - SampleDTO(name=kang, age=11)
와 같이 뜬다. 쿼리스트링으로 전달된 name과 age를 스프링이 알아서 수집해준 것이다.
개발자는 단지 SampleDTO 타입의 클래스를 파라미터로 컨트롤러에 작성해주었을 뿐인데 DTO에 동일한 이름의 인스턴스가 존재한다면 자동으로 타입까지 변환해서 처리해준 것
기본자료형이나 문자열등을 이용할 때 파라미터의 타입을 지정해줄 수 있는 어노테이션이다. 쿼리스트링으로 전달된 파라미터와 컨트롤러에 작성된 메서드의 변수 이름이 같다면 사용할 필요는 없지만 만약 다르다면 유용하게 사용 가능하다.
@GetMapping("/ex02")
public String ex02(@RequestParam("name") String myname, @RequestParam("age") int myage) {
log.info("name : " + myname);
log.info("age : " + myage);
return "ex02";
}
테스트
http://localhost:8181/controller/sample/ex02?name=kang&age=22
INFO : com.minsung.controller.SampleController - name : kang INFO : com.minsung.controller.SampleController - age : 22
동일한 이름의 파라미터가 여러개 전달되는 경우
1) ArrayList<> 사용
@GetMapping("/ex02List")
public String ex02List(@RequestParam("ids") ArrayList<String> ids) {
log.info("전달된 여러개 ids : " + ids);
log.info("ids 개수 : "+ ids.size());
return "ex02";
}
http://localhost:8181/controller/sample/ex02List?ids=111&ids=22&ids=
INFO : com.minsung.controller.SampleController - 전달된 여러개 ids : [111, 22, ]
INFO : com.minsung.controller.SampleController - ids 개수 : 3
⚠주의) 스프링은 파라미터의 타입을 보고 객체를 생성하므로 파라미터의 타입은 List<>와 같이 인터페이스 타입이 아닌 실제적인 클래스 타입으로 지정할 것
2) 배열 사용
@GetMapping("/ex02Arr")
public void ex02Arr(@RequestParam("ids") String[] ids) {
log.info("전달된 여러개 ids : " + Arrays.toString(ids));
log.info("ids 개수 : "+ ids.length);
}
이하 동일
전달하는 데이터가 SampleDTO같은 객체타입이고, 여러개를 처리해야 한다면 SampleDTOList 클래스를 만들어 한꺼번에 처리할 수 있다.
package com.minsung.domain;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Data
public class SampleDTOList {
private List<SampleDTO> list;
public SampleDTOList() {
list = new ArrayList<SampleDTO>();
}
}
⬇Controller에 작성⬇
@GetMapping("/ex02Bean")
public void ex02Bean(SampleDTOList list) {
log.info("전달된 dto들 : " + list);
}
파라미터를 '[인덱스]' 형태로 전달해서 처리 한다.
프로젝트경로/sample/ex02Bean?list[0].name=aaa&list[1].name=bb
tomcat버전에 따라서 [ , ] 대괄호들은 특수문자로 허용되지 않을 수 있다.
그러면 javasciprt로 encodeURIComponent() 사용을 하던가
[ 는 %5B
] 는 %5D로
변경