■ MVC 관련 Spring annotation - 2
목차
@Service
@Repository
@Controller
@RequestMapping
@requestParam
@ModelAttribute
@SessionAttributes
@InitBinder
@Service
개요 : @Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다.
Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며
Service에 있는 @Autowired는 @Repository("xxxDao")에 등록된 xxDao와 변수명이 같아야 한다.
1 2 3 4 5 6 7 8 9 | @Service( "helloService" )
public class HelloServiceImpl implements HelloService {
@Autowired
private HelloDao helloDao;
public void hello() {
System. out .println( "HelloServiceImpl :: hello()" );
helloDao.selectHello();
}
}
|
helloDao.selectHello(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다.
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Service( "test2.testService" )
//괄호 속 문자열은 식별자를 의미한다.
//괄호를 생략할 경우 클래스명 그대로 사용한다.
//따라서 ,같은 클래스명이 존재 할 시 같은 식별자가 생성되기때문에 에러가 발생한다.
public class TestService
{
public String result( int num1, int num2, String oper)
{
String str = null ;
if(oper.equals( "+" ))
{
...
생략
...
return str;
}
}
|
@Resouce로 연결
1 2 3 4 5 6 7 8 9 10 | @Resource( name = "test2.testService" )
// name 에 필요한 것은 @Service( "test2.testService" ) <- 여기서 괄호 속 문자열, 즉 식별자
private TestService service;
//TestService service = new TestService(); 라고 하는것과 같은 식
@RequestMapping(value= "/test2/oper.action" , method={RequestMethod.GET})
public String form() throws Exception
{
return "test2/write" ;
}
|
@Repository
패키지 : org.springframework.stereotype
버젼 : spring 2.0
개요 : 레포지 토리 어노테이션은 일반적으로 DAO에 사용되며 DB Exception을 DataAccessException으로 변환한다.
예제
1 2 3 4 5 6 7 8 9 10 | @Repository( "bbs.boardDAO" )
public class BoardDAO
{
private SqlSession sqlSession;
public int insertBoard(Board dto) throws Exception
{
...
}
}
|
1 2 3 4 5 6 7 | public class BoardServiceImpl implements BoardService
{
@Resource( name = "bbs.boardDAO" )
private BoardDAO dao;
public int insertBoard(Board dto){}
}
|
@Controller
패키지 : org.springframework.stereotype
버젼 : spring 2.5
개요 : spring MVC의 Controller 클래스 선언을 단순화시켜준다. 스프링 컨트롤러,
서블릿을 상속할 필요가 없으며, @Controller로 등록된 클래스 파일에 대한 bean을 자동으로 생성해준다.
Controller로 사용하고자 하는 클래스에 @Controller 지정해 주면 component-scan으로 자동 등록된다.
- xml 설정
1 2 | <context:component-scan base-package= "han.*" >
</context:component-scan>
|
- java
1 2 3 4 5 6 7 | package han.test;
import org.springframework.stereotype.Controller;
@Controller
public class SpringC {
}
|
@RequestMapping
개요 : RequestMapping annotation은 url을 class 또는 method와 mapping 시켜주는 역활을 한다. annotation을 쓰지 않을때 지정했던 Controller등록을 위한 url bean 설정을 생략 할 수 있다.
class에 하나의 url mapping을 할 경우, class위에 @RequestMapping("/url")을 지정하며
, GET 또는 POST 방식 등의 옵션을 줄 수 있다.
해당되는 method가 실행된 후, return 페이지가 따루 정의되어 있지 않으면 @RequestMapping("/url")에서
설정된 url로 다시 돌아간다.
수업예제
1 2 3 4 5 6 7 8 9 10 11 12 | @RequestMapping(value= "/test3/oper.action" [, method=RequestMethod.POST])
public ModelAndView submit( int num1, int num2, String oper) throws Exception
{
....
}
//요청된 URL에 따라 호출될 메서드를 지정한다.
//클라이언트가 /test3/oper. action 을 요청하면 위 메서드가 실행된다는 것이다.
//단, method 지정을 하면 해당 프로토콜에 해당된 요청에만 반응한다.
//여기서 method 는 get/post 둘 다 지정할 수도 있다.
@RequestMapping(value= "/..." , method={RequestMethod.GET, RequestMethod.POST})
method=...get || method={...get, ...post}
|
상세 속성 정보
(1) value : "value='/getMovie.do'"와 같은 형식의 매핑 URL 값이다. 디폴트 속성이기 때문에 value만 정의하는 경우에는 'value='은 생략할 수 있다.
예 : @RequestMapping(value={"/addMovie.do", "/updateMovie.do" })
|
이와 같은 경우 "/addMovie.do", "/updateMovie.do" 두 URL 모두 처리한다.
(2) method : GET, POST, HEAD 등으로 표현되는 HTTP Request method에 따라 requestMapping을 할 수 있다. 'method=RequestMethod.GET' 형식으로 사용한다. method 값을 정의하지 않는 경우 모든 HTTP Request method에 대해서 처리한다.
예 : @RequestMapping(method = RequestMethod.POST)
|
위의 경우 value 값은 클래스 선언에 정의한 @RequestMapping의 value 값을 상속받는다.
(3) params : HTTP Request로 들어오는 파라미터 표현이다. 'params={"param1=a", "param2", "!myParam"}' 로 다양하게 표현 가능하다.
예 : @RequestMapping(params = {"param1=a", "param2", "!myParam"})
|
위의 경우 HTTP Request에 param1과 param2 파라미터가 존재해야하고 param1의 값은 'a'이어야하며,
myParam이라는 파라미터는 존재하지 않아야한다. 또한, value 값은 클래스 선언에 정의한 @RequestMapping의 value 값을 상속받는다.
(4) headers : HTTP Request의 헤더 값이다.'headers="someHader=someValue"', 'headers="someHader"', 'headers="!someHader"' 로 다양하게 표현 가능하다. Accept나 Content-Type 같은 헤더에 대해서 media type 표현 시 '*' 도 지원한다.
예 : @RequestMapping(value="/movie.do", headers="content-type=text/*")
|
위의 경우 HTTP Request에 Content-Type 헤더 값이 "text/html", "text/plain" 모두 매칭이 된다. 또한,
Type-Level, Method-Level에서 모두 사용할 수 있는데, Type-Level에 정의된 경우, 하위의 모든 핸들러 메소드 에서도 Type-Level에서 정의한 헤더값 제한이 적용된다.
- 사용 예
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Controller
@RequestMapping( "/han/test/*" )
public class HelloController
{
@RequestMapping(method=RequestMethod.GET, value= "go" )
public returntype getMethodName(){
:
}
@RequestMapping(method=RequestMethod.POST, value= "go2" )
public returntype getMethodName2(){
:
}
}
|
1 2 3 4 5 6 7 8 9 10 | @Controller( "mainController" )
@RequestMapping(value= "/main.action" )
public class MainController {
@RequestMapping(method=RequestMethod.GET)
public String method() {
return ".mainLayout" ;
}
}
|
@RequestParam
개요 : RequestParam annotation은 key=value 형태로 화면에서 넘어오는 파라미터를 맵핑 된 메소드의
파라미터로 지정해 준다. 주로 get 방식으로 들어오는 request에서 사용한다.
아래에서 xxx/editBlog.do?blogId=3 과 같이 접근할 때, editBlogHandler 메소드의 파라미터인 blogId에는 3이 셋팅된다. 필수 요건이 아닐 경우, @RequestParam(value="id", required="false")와 같이 옵션을 주고 사용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 | @Controller
public class BlogController {
/* 중간생략 */
@RequestMapping( "/editBlog" )
public ModelMap editBlogHandler(@RequestParam( "blogId" ) int blogId) {
blog = blogService.findBlog(blogId);
return new ModelMap(blog);
}
/* 중간생략 */
}
|
수업예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @RequestMapping(value= "/..." , method={RequestMethod.GET, RequestMethod.POST})
public String submit(HttpServletRequest req
, @RequestParam(value= "num1" ) int num1
, @RequestParam(value= "num2" ) int num2
, @RequestParam(value= "oper" ) String oper) throws Exception
{
... //value : form객체가 넘겨줄 값의 name
}
//@RequestParam 어노테이션이 적용된 파라미터는 기본적으로 필수 파라미터이다.
따라서, 명시한 파라미터가 존재하지 않을 경우 400 에러가 발생한다.
//여기서 파라미터에 값이 있을수도 없을수도 있는 로직을 구현하려면 다음처럼 작성한다.
@RequestMapping(value= "/..." , method={RequestMethod.GET, RequestMethod.POST})
public String submit(HttpServletRequest req
, @RequestParam(value= "num1" , defaultValue = "0" ) int num1
, @RequestParam(value= "num2" , defaultValue = "0" ) int num2
, @RequestParam(value= "oper" , required= false ) String oper) throws Exception
{
...
}
|
@ModelAttribute
개요 : ModelAttribute annotation은 화면의 form 속성으로 넘어온 model을 맵핑된 method의 파라미터로 지정해주는 역활을 한다. 주로 POST 타입으로 넘어오는 form 속성의 model 값을 받아 올 때 사용된다.
(get/post 모두 통용된다.)
1 2 3 4 5 6 7 8 9 10 11 12 | @Controller
public class BlogController {
/* 중간생략 */
@RequestMapping( "/updateBlog" )
public String updateBlogHandler(@ModelAttribute( "blog" ) Blog blog) {
blogService.updateBlog(blog);
return "redirect:findBlogs.do" ;
}
/* 중간생략 */
}
|
@SessionAttributes
개요 : SessionAttribute annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용 할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Controller
@SessionAttributes( "blog" )
public class BlogController {
/* 중간생략 */
@RequestMapping( "/createBlog" )
public ModelMap createBlogHandler() {
blog = new Blog();
blog.setRegDate(new Date ());
return new ModelMap(blog);
}
/* 중간생략 */
}
|
@InitBinder
ο Annotation 기반 Controller 에서 ServletContext 구하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | :
@Controller
@RequestMapping( "/common/download" )
public class DownloadController {
@Autowired
private ServletContext sc;
@RequestMapping
public ModelAndView download(@RequestParam( "filePath" ) String filePath) throws Exception
{
String path = sc.getRealPath(filePath);
return new ModelAndView( "common.download" , "downloadFile" , new File(path));
}
}
|