Spring으로 방명록 애플리케이션을 구현하는 시리즈입니다.




이 글에서는 방명록 애플리케이션을 만들기 전에, 스프링을 다루는 기본적인 방법을 알아보도록 하겠습니다.

실습 환경은 바로 이전 글을 참고해주세요.




구조적인 URL 매핑

GuestBookController에서 /main 요청을 처리하는 방법


방법 1

@Controller
public class GuestBookController {
	@Autowired
	private GuestBookDAO guestbookDAO;
	
	@RequestMapping("/main")
	public String main() {
		return "/WEB-INF/views/index.jsp";
	}
}


방법 2

@Controller
@RequestMapping("/main")
public class GuestBookController {
	@Autowired
	private GuestBookDAO guestbookDAO;
	
	@RequestMapping("/")
	public String main() {
		return "/WEB-INF/views/index.jsp";
	}
}


방법1은 메서드에 직접 URL 매핑을 했습니다.

방법2는 컨트롤러에 매핑을 한 후, 세부적으로 메서드에서 URL 매핑을 했습니다.


일반적으로 컨트롤러 클래스는 비슷한 류의 요청들을 처리하는 것이 일반적이기 때문에 컨트롤러에 URL 매핑을 한 후, 메서드에 세부적으로 URL을 명시하는 것이 좋습니다.

방법2를 요청할 때는 http://localhost:8080/guestbook/main/ 와 같이 끝에 /를 붙여야 합니다.





파라미터 받기

@RequestMapping("/")
public String main(@RequestParam String a) {
	System.out.println(a);
	return "/WEB-INF/views/index.jsp";
}

http://localhost:8080/guestbook/main/?a=hi 로 URL 요청을 보내면 콘솔창에 파라미터 a의 값인 hi 가 찍히는 것을 확인할 수 있습니다.


만약 파라미터 a를 넘겨주지 않는다면 에러가 발생합니다.

이에 대한 해결책은 @RequestParam() 어노테이션에 속성을 추가하면 됩니다.


@RequestMapping("/")
public String main(
		@RequestParam(value="a", required=true, defaultValue="bye" ) String a){
	System.out.println(a);

	return "/WEB-INF/views/index.jsp";
}

@RequestParam 어노테이션의 괄호 안에 여러 속성들을 추가했습니다.

required는 파라미터 a가 꼭 필요한지 여부를 boolean으로 정의하고,

defaultValue는 파라미터 a가 없을 때 기본 값으로 어떤 값을 기본 값으로 설정할 것인지 작성할 수 있습니다.


위와 같이 작성하고 http://localhost:8080/guestbook/main/ 으로 요청을 보내면 콘솔창에 bye가 찍히는 것을 확인할 수 있습니다.

파라미터 a를 넘겨주지 않았기 때문이죠.





VO 객체를 통째로 받기 ( 커맨더 객체 ) 

@RequestMapping("/")
public String main(@ModelAttribute GuestBookVO vo){
	System.out.println( vo.getName() );
	System.out.println( vo.getContent() );

	return "/WEB-INF/views/index.jsp";
}

@ModelAttribute 어노테이션을 사용하면 객체를 통째로 받을 수 있습니다.


예를들어 form에서 <input> 태그의 name이 name, title, content인 데이터가 서버로 전달되었다고 가정하겠습니다.

그러면 컨트롤러 내부에서는 form에 입력된 데이터가 vo 객체에 할당 됩니다.

중요한 것은 form의 <input> 태그의 name 속성과 VO 객체의 인스턴스 변수의 이름이 정확히 일치해야 한다는 것입니다.


만약 GuestBookVO 클래스에 email 이라는 인스턴스 변수가 있는데, form에서 email 이름으로 입력 값이 넘어오지 않는다면,

null로 처리가 될 뿐 에러는 발생하지 않습니다.


form으로 전송된 데이터를 일일이 @RequestParam으로 받는 것보다 객체로써 통째로 받는 것은 매우 편리하기 때문에, 자주 사용되는 방식입니다.


그리고 스프링은 getter, setter를 이용하기 때문에 꼭 VO 객체에 getter , setter가 존재해야 합니다.

나중에 살펴 볼 Mybatis도 getter, setter를 이용하니 getter , setter를 꼭 작성해야 합니다 !





HTTP 메서드 제한하기

@RequestMapping(value="/", method=RequestMethod.POST)
public String main(@RequestParam(value="a", required=false) String a){
	System.out.println(a);
	return "/WEB-INF/views/index.jsp";
}

@RequestMapping 어노테이션에 method 속성을 추가하면 HTTP 메서드를 제한할 수 있습니다.

method 속성을 작성하지 않는다면 모든 HTTP 메서드를 받아들인다는 기본 값이 설정되어 있습니다.


위의 코드는 /guestbook/main/ 요청에 대해 POST방식만 받을 수 있도록 제한하고 있습니다.

따라서 http://localhost:8080/guestbook/main/ 으로 요청을 하면 에러가 발생할 것입니다.

RequestMethod.GET 으로 수정한다면 정상적으로 응답 됩니다.


이 방식은 RESTful하게 작성할 때 자주 사용됩니다.





URL 경로를 변수로 받아내기

@RequestMapping(value="/{no}")
public String main(@PathVariable("no") Integer no){
	System.out.println(no);

	return "/WEB-INF/views/index.jsp";
}

@PathVariable 어노테이션을 사용하면 URL경로를 변수로 처리할 수 있습니다.

http://localhost:8080/guestbook/main/10  경로로 요청을 해보시면 콘솔 창에 10이 찍히는 것을 확인할 수 있습니다.


이 경우 URl에서 main/ 이후에는 어떤 문자열이든 올 수 있지만, 특정 문자열은 제외 시키고 싶을 수도 있습니다.

@RequestMapping(value="/{no:(?!assets|image|search).*}", method=RequestMethod.GET)

이렇게 어노테이션을 수정하면 " main/ 이후의 문자열 중 assets , image , search 문자열을 제외한 모든 값은 no 변수로 받는다 "는 의미가 됩니다.





리다이렉트

@RequestMapping("/")
public String main(){
	System.out.println("리다이렉트되어 돌아옴");

	return "/WEB-INF/views/index.jsp";
}

@RequestMapping("/redirect")
public String redirectTest(){

	return "redirect:/main/";
}

리다이렉트는 HTTP 헤더에 응답 코드 302와 새로운 경로를 클라이언트에게 전달함으로써, 클라이언트가 새로운 경로로 요청을 하도록 하는 기법입니다.

스프링에서는 return "redirecct:경로"; 를 작성함으로써 리다이렉트를 할 수 있습니다.


URL에 http://localhost:8080/guestbook/main/redirect 을 요청하면 브라우저에 index.jsp 페이지와 함께 콘솔 창에 메시지가 출력 될 것입니다.

즉 main 메서드가 실행된 것이죠.


물론 redirect 할 때도 파라미터를 전달할 수 있습니다.

return "redirect:/main/?a=10"; 





JSP로 데이터 넘기기

@RequestMapping("/")
public String main(Model model){
	List<guestbookvo> list = guestbookDAO.getList();
	model.addAttribute("list", list);

	return "/WEB-INF/views/index.jsp";
}

위 코드의 컨트롤러 내부동작은 다음과 같습니다.

ViewResolver가 View 객체를 가져오면 Model객체는 View 객체에 데이터를 추가합니다.

그리고 이 View 객체를 반환하는 것이죠.


Model 객체를 통해 JSP로 데이터를 넘길 수 있습니다.

그러면 JSP에서는 list라는 이름으로 List 객체를 사용할 수 있습니다.

아래의 코드는 JSTL을 사용하여 JSP에 데이터를 찍는 예시입니다.



컨트롤러에서 전달한 list를 JSP에서 그대로 사용하는 것을 확인할 수 있습니다.


참고로 ModelAndView라는 객체도 있는데 이 객체는 위의 방식과 똑같지만 ModelAndView 객체를 반환합니다.





이상으로 컨트롤러에서 할 수 있는 기본적인 활용법을 다뤄보았습니다.

URL을 어떻게 매핑시키고, 데이터를 어떻게 전달하며, 응답을 어떻게 하는지를 알면 방명록 애플리케이션 만드는 일은 어렵지 않습니다.

다음 글에서는 본격적으로 방명록 애플리케이션을 구현해 보도록 하겠습니다.