최범균의 스프링책과 인터넷 검색 결과를 바탕으로 만든 자료입니다.

스프링 MVC는 html form 안의 데이터를 자바빈 객체로 전달받을 수 있다.
기본빈이다. 말그대로 get/set을  정의한 표준빈 형태...

방법은 간단하다.

1. 폼 데이터 받기
HTML폼의 데이터를 자바빈으로 가져오려면, 
@RequestMapping 어노테이션을 적용한 메소드의 파라미터에 자비빈 타입을 추가하기만 하면된다. (이를 커맨드객체라고 하는건가??? )

그게... 만약 html의 form 에 input 의 name에 맞는 set/get 을 가진 빈을 만들어 넣으면 거기에 값이 들어가있는것...

@RequestMapping(method = RequestMethod.POST)
public String submit(폼에맞춘빈클래스 command) {
command.getXxx();
        .... 
}

2. 뷰에서 데이터 접근
위의 내용을 view 에서 접근할 수 있는데 JSTL EL로 접근한다.

예로, NewArticleCommand 타입의 커맨드객체를 전달받았다면...
@RequestMapping(method = RequestMethod.POST)
public String submit(NewArticleCommand command) {
    ....
}

이런경우, view 에서는 클래스이름을 이용해서 객체에 접근할 수 있다.

<body>
....
제목 : ${newArticleCommand.title}
....

근데 이건 좀 아니지; 클래스명을 쓰긴 뭐하잖아? 바꿀 수 있다.


@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
articleService.writeArticle(command);
return "article/newArticleSubmitted";
}


<body>
....
제목 : ${command.title}
....
 

3. 뷰에서 콜렉션 타입 받기 
특별한것도 없고 List 타입의 값을 받으면된다.
다음엔 xxx[i].변수
로.. [인덱스] .. 배열처럼 접근하면된다.


4. 컨트롤러가 있는 RequestMapping된 메서드의 파라미터 종류
@RequestMapping 이 적용된 메소드에는 커맨드클래스 말고도 HttpServletRequest, HttpSession, Locale 등 웹 어플리케이션 관련 다양한 타입의 파라미터를 가질 수 있다.

종류...
 파라미터 타입설명 
 HttpServletRequest, HttpServletResponse HttpSession 서블릿
 java.util.Locale 현재 요청에 대한 Locale
 InputStream, Reader 요청 컨텐츠에 직접 접근할 때 사용
 OutputStream, Writer 응답 컨텐츠를 생성할 때 사용
 @PathVariable 어노테이션적용 파라미터 URI 템플릿 변수에 접근할 때 사용
 @RequestParam 어노테이션 적용 파라미터 HTTP 요청 파라미터를 매핑
 @RequestHeader 어노테이션 적용 파라미터HTTP 요청 헤더를 매핑 
@CookieValue 어노테이션 적용 파라미터 HTTP 쿠키 매핑 
@RequestBody 어노테이션 적용 파라미터 HTTP 요청의 몸체 내용에 접근할 때 사용. 
HttpMessageConverter를 이용해서 HTTP 요청 데이터를 해당 타입으로 변환한다. 
 Map,Model,ModelMap 뷰에 전달할 모델 데이터를 설정할때 사용
커맨드 객체 HTTP 요청 파라미터를 저장한 객체. 기본적으로 클래스이름을 모델명으로 사용. @ModelAttribute 어노테이션을 사용하여 모델명을 설정할 수 있다.
 Errors,BindingResult HTTP 요청 파라미터를 커맨드 객체에 저장한 결과, 커맨드 객체를 위한 파라미터 바로 다음에 위치
 SessionStatus폼 처리를 완료 했음을 처리하기 위해 사용. @SessionAttribute 어노테이션을 명시한 session 속성을 제거하도록 이벤트를 발생시킨다. 


Errors와 BindingResult는 연관된 커맨드 객체 바로 다움에 와야한다. (메소드의 파라미터 위치에 말야) 이 두 타입을 제외한 나머지 타입은 순서에 상관없다.



4.1 @RequestParam

컨트롤러 구현시 가장 많이 쓴단다.
HTTP 요청 파라미터를 메소드의 파라미터로 전달받을때 사용.

즉 html로 요청을 받을때 존재하는 파라미터를 바로 어떤 변수와 매핑시키는 역할이다.
사실 이건 그냥 꺼내와서 변수에 넣으면 ... 이게 바로 @RequestParam 어노테이션이 하는 내용과 같아진다.


ex)
.../search/internal.do?query=spring&p=3

@RequestMapping("/search/internal.do")
public ModelAndView searchInternal(@RequestParam("query") String query,
                               @RequestParam(value = "p", defaultValue = "1") int pageNumber) {
        ...
}

딱보니 뭔지 알겠지?

만약 위에서 p 값에 숫자가 아닌 값이 오게 되면 400 에러를 웹 브라우저에 보낸다. (Bad Request)
@RequestParam이 오면 필수 파라미터가 된다. 이를 필수가 아니게 하고 싶다면...?

required=false 이다.

@RequestMapping("/search/external.do")
public ModelAndView searchExternal(@RequestParam(value="query", required=false) String query,
                                                @RequestParam(value = "p", defaultValue = "1") int pageNumber) {
 
만약 필수 파라미터인데 html에서 오지 않았다면? null을 할당한다.
허나.. 그 타입이 null을 할당할 수 없다면? 에러를 발생한다;; 이를 피하기 위해서 defaultValue를 이용한다.



4.2 @CookieValue 어노테이션

쿠키값을 전달받을 수 있다.

@RequestMapping("/cookie/view.do")
public String view( @CookieValue( "auth" ) String auth) {

위의 경우 auth 라는 쿠키를 찾는데 없으면 500 에러가 나온다.
이때 required=false 하면, null을 전달 받는다.

@RequestMapping("/cookie/view.do")
public String view( @CookieValue(value="auth" , required=false ) String auth) {


defaultValue를 통한 값 설정도 가능하다.
@RequestMapping("/cookie/view.do")
public String view( @CookieValue(value = "auth", defaultValue = "0") String auth) {
 

4.3 @RequestHeader 어노테이션을 이용한 헤더 매핑
HTTP 요청 헤더의 값을 메소드 파라미터로 전달한다.
(즉... UA 값등...)


@RequestMapping("/header/check.do")
public String check(@RequestHeader("Accept-Language") String languageHeader) {
...
}

역시 헤더에 값이 존재 하지 않으면 500리턴한다. 역시 required 및 defaultValue 값을 설정할 수 있다.

4.4 서블릿 API 사용 (HttpServletRequest, HttpServletResponse , HttpSession)

보통은 안쓰지만, 사용하게 되는 경우는...
ㄱ. HttpSession의 생성을 직접 제어해야하는 경우
ㄴ. 컨트롤러에서 쿠키를 생성해야 하는 경우
ㄷ. 서블릿 API 사용을 선호하는 경우

HttpSession 타입의 파라미터를 가질경우,  
기존의 세션이 존재하면 그게오고, 없다면 새로 세션이 생성되어서 온다.
하여 null일 수 없다.


 

5. 뷰 이름 지정
5.1 뷰 이름 명시적 지정


뷰이름을 명시적으로 지정하려면 ModelAndView 나 String을 리턴하면된다.

@RequestMapping("/index.do")
public ModelAndView index() {
ModelAndView mav = new ModelAndView("index");
            ....
            return mav;
}

위처럼 생성자를 통해서나 serViewName() 을 통해서 지정할 수 있다.

아니면 리턴타입을 String으로 해서

public String index() {
    return "index";
}

로 할수도 있다.

5.2 뷰 이름 자동 지정

ㄱ. 리턴타입이 Model 이나 Map 인경우
ㄴ. 리턴 타입이 void 이면서 ServletResponse 나 HttpServletResponse 타입의 파라미터가 없는 경우.

위의 경우는 RequestToViewNameTranslator를 이용해서 URL로 부터 뷰 이름을 구한다.

.xml 설정파일에 RequestToViewNameTranslator 빈이 존재하지 않을 경우는 DefaultRequestToViewNameTranslator가 사용된다.

DeafultRequestToViewNameTranslator 는 요청 URI로부터 맨 앞의 슬래시와 확장자를 제외한 나머지 부분을 뷰 이름으로 사용한다.
(즉, 전체경로를 사용하지 않도록 설정한 경우 서블리 경로를 제외한 나머지 경로가 사용된다)

@RequestMapping("/search/game2.do")
public Map<String,Object> search() {
    HashMap<String,Object> model = new HashMap<String,Object>();
    ....
    return model;
}

위예제에서는 뷰에서 쓸 데이터모델을 Map을 이용한 모델로 리턴하고 있다. 이 경우 RequestToViewNameTranslator 를 이용해서 
결과를 보여줄 뷰 이름을 결정하게 된다. DefaultRequestToViewNameTranslator가 사용될 경우

ex) /search/game2.do --> search/game2


5.3 리다이렉트 뷰 

뷰 이름에 redirect: 접두어를 붙이면 해당 페이지로 리다이렉트된다.

- redirect: /bbs/list  --> 현재 서블릿 컨텍스트에 대한 상대적인 경로로 리다이렉트
- redirect: http://host/bbs/list --> 지정한 절대  URL로 리다이렉트











+ Recent posts