[Spring] Spring MVC Controller

msriver·2020년 6월 23일
0

Spring

목록 보기
10/16

Spring MVC Controller의 특징

  • HttpServletRequest, HttpServletResponse를 거의 사용할 필요 없음.
  • 다양한 타입의 파라미터/리턴 사용 가능
  • GET/POST 등 전송방식에 대한 처리를 어노테이션으로 가능
  • 상속/인터페이스 방식 대신에 어노테이션만으로도 필요한 설정 가능

예제 컨트롤러

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의 변신

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 방식등을 처리할 수 없다.

Controller 파라미터 수집

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에 동일한 이름의 인스턴스가 존재한다면 자동으로 타입까지 변환해서 처리해준 것

@RequestParam

기본자료형이나 문자열등을 이용할 때 파라미터의 타입을 지정해줄 수 있는 어노테이션이다. 쿼리스트링으로 전달된 파라미터와 컨트롤러에 작성된 메서드의 변수 이름이 같다면 사용할 필요는 없지만 만약 다르다면 유용하게 사용 가능하다.

@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로
변경

profile
NOBODY

0개의 댓글