학원/SPRING

12/07 59-1 [SPRING] 핸들러매핑/컨트롤러/뷰리졸버

도원결의 2022. 12. 7. 21:44

개념설명은 대충하고 넘어가겠음 그건 주말이나 그때 다시 정리하고(할 수 있을 까..)

[Spring의 주요 특징]

1. 스프링은 POJO (Plain Old Java Object) 방식의 프레임워크로서, 일반적인 J2EE 프레임워크에 비해 특정 라이브러리를 사용할 필요가 없어서
개발이 쉬우며, 기존 라이브러리의 지원이 용이.

다시 예시
public B b(){} 요거 만든거 쓰려면()
B b = new B() 이렇게 썼는데 이젠 달라 B를 생성하는게 아니라(new 하는게 아니라) 컨테이너에 의해서 주입을 받아 쓴다!!

스프링은 의존성 주입, DI (Dependency Injection)를 지원. 이는 객체간의 의존관계를 관리하는 기술로. 어떤 객체가 필요로 하는 객체를
자기 자신이 직접 생성하는것이 아니라, 외부에 있는 다른곳에서 자신이 필요로 하는 객체를 주입받는것을 말한다.


[Spring web MVC] model view controller?
- 요청을 처리하기 위해 컨트롤러를 선택하는 방법과 결과를 보여주기 위해
뷰를 선택하는 방식간에 낮.은. 결.합.도.를. 유지하고 있다는 점이 무엇보다 중요함.
(테스트 용의, 유지보수 유리)

DispatchServlet을 여러 개 등록할 수 있다. 각각의 DispatcherServlet은 서로 다른 WebApplicationContext를 생성하는데
각각의 WebApplicationContext에서 생성된 자바빈은 서로 공유가 안된다.
즉 DispatcherServlet이 인스턴스화될 때 생성되는 WebApplicationContext 간에 공통으로 사용하는 자바빈을
ContextLoaderListener를 통해 등록 할 수 있고 또는 root-context.xml 에서 등록 할 수 있다.
따라서 ContextLoaderListener에 의해 생성된 자바빈은 모든 DispatcherServlet에서 공유할 수 있다. 자자 다시 정리
listener = rootcontext라고 생각하고
DispatcherServlet이 여러 개 일 경우 각각의 객체들은 서로다른 DispatcherServlet에서 는 공유가안됨
공유하려면 listener = rootcontext에 객체정의를 하면 된다..

 

컨트롤러가 요런 흐름!!!



흐름 다시 이해해 보자 크게크게 보자
  =>비유를 들으면 쉬우려나: 레스토랑이라고 가정,서빙하는 사람(DispacherServlet)과 컨트롤하는 매니저(HandlerMapping) 그리고  여러명의 주방장(Controller)이 있음 

1. 사용자의 모든 요청을 DispacherServlet(Front Controller의 역할 즉 관문)이 받는다 (요청 다 받아!!)
 =>서빙하는 사람이 주문을 받음
2. DispatcherServlet은 요청을 어느 컨트롤러에게 전달할지를 HandlerMapping을 이용해 결정한다. (어느 컨트롤러를 이용?)
 =>매니저에게 어떤 주방장님에게 요청 할까요 ?  물어봄
3. DispatcherServlet은 요청을 전달할 컨트롤러를 결정한 후 해당 Controller에게 요청을 넘긴다(요새는 @어노테션을 사용한다!!!)
 =>2번 주방장님 스테이크 구워주세요
4. Controller는 별도로 작성한 비즈니스 모델에서 필요한 로직을 호출한 후 그 결과를 받아서
결과 데이타와 어떤 View를 보여줄지를 ModelAndView개체에 저장한 후 DispatcherServlet에 전달한다.
(어디다가 무엇을 뿌려라!! )
 =>주방장이 음식 조리 후 서빙하는 사람이 건네받음
5. DispatcherServlet은 View에 대한 정보를 담고 있는 ViewResolver를 참조해서 Model를 뿌려줄 View정보를 얻는다.
(물리적/상대적 경로를 따라서 뿌려라!!)
 => 5번 테이블(View정보)로 서빙 하세요!
6. 요청한 사용자에게 View를 전달한다.
 => 서빙완료!



우선 들어가고 보자

이제 index를 쓸 거라서

homecontroller를 먼저 좀 변경 해 놓자(기존에 있던거 변경해서 사용) 

@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	//@RequestMapping(value = "/", method = RequestMethod.GET)
	@RequestMapping(value = "/index.do", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		
		//return "home";
		return "index";
	}
}

 

 

servlet-context.xml

여기서 빈이라는것을 생성함 ! 음... 쉽게말하면 객체를 생성하는 곳? 컨트롤러가 new를 만들어 내는 곳 이라고 생각하자

근데 @어노테이션 기능이 생기면서 부터 여기서 빈 생성하는 경우는 거의 사라졌다고 함

여기서 빈 생성하고 컨트롤러로 왔다갔다 하는 것 보다 컨트롤러페이지에다가 걍 @ 요거로 처리하는게 더 쉽고 빠름 !

이건 경험 해 보면 알아..

 

index.jsp 

경로설정 : /컨트롤러명.kosmo

<h2>1. DispatcherServlet <small><a href="<c:url value="/dispatcher.kosmo"/>">디스패처 서블릿</a>${dispatcher}</small></h2>

여기다가 구현 할 것들을 하나 씩 차곡차곡 쌓을 거임

jsp파일에서는 어떻게 컨트롤러랑 연결 되는 지 코드를 잘 봐두자 !

경로 설정 할 때 / 있는지 잘 확인 하자 !! 왜냐면 이거 때문에 엄청 고생했음....

그리고 web.xml 가서 welcom-file 설정을 index.jsp로 맨 위에다가 해 놓으면 서버 실행할 때 index.jsp가 가장 먼저 실행 됨

그니까 그렇게 설정해 놓으라고...!

jsp에 코드를 보니 dispatcher.kosmo가 요청을 처리하는 것 같으니 이 컨트롤러를 만들어야 겠지?

 

WEB-INF > Myservlet-servler.xml

경로설정 : /컨트롤러명.kosmo

여기서 빈을 먼저 생성하거나 아니면 바로 컨트롤러로 가서 @어노테이션을 설정 하거나 인데

우리는 공부를 위해서 빈을 생성 해 볼 것임

**사용자 요청을 처리할 빈 등록**
 name : 요청 URL 패턴
 class : 패키지를 포함한 컨트롤러의 클래스명

<bean name="/dispatcher.kosmo" class="com.kosmo.springapp.DispatcherController"/>


src/main/java > con.kosmo.springapp
Dispatchercontroller.java

 

 어노테이션 미 사용시 Controller 인터페이스나 Controller계열 클래스를 상속받아 컨트롤러로 구현
 대부분의 Controller계열 클래스가 deprecated됨

public class DispatcherController implements Controller {
	
	public DispatcherController() {
		System.out.println("DispatcherController 생성자 호출");
	}

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
	/*
	  	ModelAndView 객체에 뷰 정보와 모델(데이터)을 담아 디스패처 서블릿에게 반환
	  	뷰정보 : /WEB-INF/views/index.jsp
	  	데이터정보 
	 	속성명 : dispatcher
	  	속성값 : 또 다른 웹 어플리케션 컨텍스트 영역입니다.
	  */		
	 return new ModelAndView("/WEB-INF/views/index.jsp","dispatcher"," 또 다른 웹 어플리케션 컨텍스트 영역입니다.");
	}

}


이미지/css 폴더랑 파일을 넣어 볼 거임

미리 main > webapp  파일에다가 이미지등 넣어 놓기!

 

그리고 servlet-context.xml  다시 가봐
<resources mapping="/resources/**" location="/resources/" />
이게 기본설정인데
기본설정의 mapping과 location
mapping: HTML에서 경로 지정 시 사용할 가상의 경로
location : wepapp아래의 실제 디렉토리 경로
그려면 설정한 요 경로 안에서만 읽어올 수 있는거 같음!!
하지만 우리는 webapp아래 아무곳이나 폴더를 만들어 리소스를 두도록 설정할 것이기 때문에
(즉 webapp의 어느 디렉토리에 리소스를 두더라도 읽어올 수 있도록 설정할 것이기 때문에)
기본설정을 지우고 (지우긴 무서우니까 주석처리 하고)
<default-servlet-handler/>
이걸 넣어준다.

경로에 기본적으로 접두사와 접미사를 넣어주네
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
</beans:bean>
	
이게 컴포넌트 스캔인데 이거 사용하면 어노테이션 매핑은 안해도 된다... (아직은 잘...모름)    
<context:component-scan base-package="com.kosm.springapp" />

 

수정하려고 보니 이제 좀 보인다!! component-scan이 어노테이션들을 다 매핑/읽어주는 기능을 하는거였어!! 그래서 어노들은 따로 매핑을 안했군

그럼  이제 매핑부터 차근차근 배워보자


[핸들러매핑]  : 컨트롤러를 찾아주는 일을 담당  매칭담당이랄까?

서블릿 등록이랑 맵핑등 관련해서는 (welcom-file 설정 여기서 보이네)

web.xml

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
<!--<url-pattern>/</url-pattern>  * 할 땐 / 있으면 안됨! 이제 모든 .do를매핑할거라는 뜻!-->
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	
	<!-- 또다른 dispatcher 등록 -->
	<!-- 디폴트 설정 파일:/WEB-INF/서블릿명 contect.xml -->
	<servlet>
		<servlet-name>myServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>myServlet</servlet-name>
		<url-pattern>*.kosmo</url-pattern>
	</servlet-mapping>
	
	<!-- index.do를 시작요청으로 설정 -->
 	<welcom-file-list>
 		<welcome-file>index.do</welcome-file>
 	</welcom-file-list>
</web-app>

 

 

indexcontroller.java

여기다가도 하나 씩 메소드 추가하면서 처리할 거임 

//컨트롤러 클래스
@Controller  //이건  컴파일러에게 "아래 클래스는사용자 요청을 처리하는 클래스다" 라는걸 알려줌
public class IndexController {
	
	//컨트롤러 메소드
	@RequestMapping("/handlerMapping.do")
	public String handlerMapping() {
		//뷰정보 반환
		return "handlermapping01/HandlerMapping"; 
	}
}

뷰정보 반환 되는 jsp를 만들어야죠 
WEB-INF > views > handlermapping01>

handlermapping.jsp

<legend class="w-auto px-3">핸들러 매핑</legend>
<h3>디폴트(기본) 핸들러 매핑</h3>
<ul class="list-unstyled">
    <li><a href="<c:url value="/HandlerMapping/BeanNameUrl.do"/>">BeanNameUrlHandlerMapping</a></li>
    <li><a href="<c:url value="/HandlerMapping/Annotation.do"/>">DefaultAnnotationHandlerMapping</a></li>				
</ul>
<h3>SimpleUrlHandlerMapping(디폴트(기본) 핸들러 매핑아님)</h3>
<ul class="list-unstyled">
    <li><a href="<c:url value="/HandlerMapping/SimpleUrlFirst.do"/>">SimpleUrlFirst.do</a></li>
    <li><a href="<c:url value="/HandlerMapping/SimpleUrlSecond.do"/>">SimpleUrlSecond.do</a></li>				
</ul>								
<kbd>${message }</kbd>

어휴 코드 보니 BeanNameUrl 과 Annotation 컨트롤러등등 만들어야 겠네..
springapp.basic.handlermapping >
BeanNameUrlcontroller (정석대로 만들어 봄 @어노 안쓰고 빈에다가 등록하고 modelandview 객체에 저장해서 반환 )

/*
  Controller 인터페이스나 Controller계열 클래스를 구현 혹은 확장해야 사용자 요청을 처리하는 컨트롤러 클래스 됨
  즉 스프링 프레임워크에서 사용자 요청을 처리할 수는 자격을 갖추게 됨.
 또한 POJO로 작성한 후 Annotation을 이용해도 컨트롤러 클래스가 됨. 
*/
//컨트롤러 클래스
public class BeanNameUrlController implements Controller{	
	//컨트롤러 메소드
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//1.요청받고 분석
		//2.비니지스로직 호출 및 결과값 받기
		//3.필요한 값을 리퀘스트 영역에 저장하거나 modelNview에 저장
		ModelAndView mav = new ModelAndView();
		//4 데이터저장
		mav.addObject("message","[BeanNameUrlHandlerMapping]");
		//뷰정보저장
		mav.setViewName("handlermapping01/HandlerMapping");
		//6.디스페처서블릿에게 modelaview반환
		return mav;
	}

}

어노 안써서 빈 등록하쟈

<!-- BeanNameUrlHandlerMapping -->
<!-- -기본 핸들러 매핑 
	-<bean>태그의 name속성에 지정한 요청명(URL패턴)과 컨트롤러 클래스를 매핑 
	     name : 컨텍스트 루트를 제외한 경로 지정(반드시 /부터) 
	     class : 요청을 처리할 컨트롤러 클래스 지정 -->	
<beans:bean name="/HandlerMapping/BeanNameUrl.do" class="com.kosmo.springapp.basic.handlermapping.BeanNameUrlController"/>

 


AnnotatioController(이건 @어노도 써서 매핑도 여기서 끝내버리고 model객체를 써서 바로 반환시킴 오 간단!)

@Controller
public class AnnotationController {
	//컨트롤러 메소드
	@RequestMapping("/HandlerMapping/Annotation.do")
	public String handleRequest(Model model) {
		//데이타 저장
		model.addAttribute("message", "[DefaulrAnnotationHandlerMapping]");
		//뷰정보 반환
		return "handlermapping01/HandlerMapping";
	}
}

 

아 핸들러 매핑은

기본도 있고 내가 추가할 수도 있음!
기본이 BeanBame이랑 Annotation
내가 추가 한 건 이제 밑에서 처리할 Simple~~ 요놈들임!

둘다 @어노 안쓸 거라서 한꺼번에 빈 설정이랑 매핑까지 같이 해놓자!

	SimpleUrlHandlerMapping 
 기본 핸들러 매핑이 아니므로 사용시에는 반드시 xml파일에 bean으로 등록 
 한 섹션안에서 여러 요청과 컨트롤러 클래스를 관리하고자 할때 주로 사용 
    
    key: 요청명(URL 패턴)(.do) <prop>엘리먼트 사이에는 컨트롤러 클래스의 id값 지정   
	아래는 new SimpleUrlHandlerMapping().setOrder(1).setMappings(Properties) 와 같다 	
	<beans:bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	
핸들러 매핑의 우선순위 설정. 기본 핸들러 매핑이 아닌 것은 반드시 지정해야 한다. 
지정안하면 우선순위가 없어서 기본 핸들러 매핑들에게만 문의한다 
<beans:property name="order" value="100"/>	
<beans:property name="mappings" >
    <beans:props>
        <beans:prop key="/HandlerMapping/SimpleUrlFirst.do">first</beans:prop>
        <beans:prop key="/HandlerMapping/SimpleUrlSecond.do">second</beans:prop>
    </beans:props>
</beans:property>
</beans:bean>
	
요청을 처리할 빈 등록, 여기서 등록하면 @어노 쓰면 안됨!!!!
SimpleUrlFirstController first = new SimpleUrlFirstController() 즉 id값이 
    인스턴스변수와 같다.프레임웍이 빈 생성 시 위와 같이 생성해줌. 
<beans:bean id="first" class="com.kosmo.springapp.basic.handlermapping.SimpleUrlFirstController"/>
<beans:bean id="second" class="com.kosmo.springapp.basic.handlermapping.SimpleUrlSecondController"/>

 

simpleUrlControllerFirst(얜 어노 안썼으니... context.xml에다가 빈 설정 해야겠네...)

//
public class SimpleUrlFirstController extends AbstractController{
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
                   		throws Exception {		
                        
		return new ModelAndView("handlermapping01/HandlerMapping","message","[SimpleUrlFirst.do]");
	}
}

 


simpleUrlControllerSecond

public class SimpleUrlSecondController extends AbstractController {

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
	
		return new ModelAndView("handlermapping01/HandlerMapping","message","[SimpleUrlSecond.do]");
	}
}

 


다음엔 컨트롤러를 집중공부 고   

컨트롤러가 진짜 일 하는 곳! 일의 로직이 있는 곳 ! 
  [컨트롤러 메소드 작성 규칙]
  접근지정자 : public
  반환타입 : 주로 String(뷰 정보를 문자열로 반환)
  메소드명 : 내 맴
  인자 : 원하는 타입을 사용할 수 있다. (단, 사용할 수 있는 타입이 정해져 있다) 
  어노테이션도 가능
  예외는 throws 할 수 있다. (선택) 

controller02>Controller.jsp 내용 뿌려 줄 곳 임 

코드 보고 컨트롤러 만들경로를 참조하자 

<fieldset class=" form-group border p-3">
    <legend class="w-auto px-3">컨트롤러${message}</legend>
    <h3>하나의 컨트롤러 클래스,하나의 컨트롤러 메소드로 여러 요청하기</h3>
    <ul class="list-unstyled" >
         <li><a href="<c:url value="/Controller/OneClass/List.do"/>">목록요청</a></li>
         <li><a href="<c:url value="/Controller/OneClass/Edit.do"/>">수정요청</a></li>
         <li><a href="<c:url value="/Controller/OneClass/Delete.do"/>">삭제요청</a></li>
         <li><a href="<c:url value="/Controller/OneClass/View.do"/>">상세요청</a></li>				
    </ul>			
    <h3>하나의 컨트롤러 클래스,하나의 컨트롤러 메소드로 여러 요청 처리하기2 </h3>
    <ul  class="list-unstyled">
         <li><a href="<c:url value="/Controller/OneClassParam/List.do?crud=read-list"/>">목록요청</a></li>
         <li><a href="<c:url value="/Controller/OneClassParam/Edit.do?crud=update"/>">수정요청</a></li>
         <li><a href="<c:url value="/Controller/OneClassParam/Delete.do?crud=delete"/>">삭제요청</a></li>
         <li><a href="<c:url value="/Controller/OneClassParam/View.do?crud=read-one"/>">상세요청</a></li>				
    </ul>							
        <h3>하나의 컨트롤러 클래스,여러개의 컨트롤러 메소드로 여러 요청 처리하기2 </h3>
    <ul  class="list-unstyled">
         <li><a href="<c:url value="/Controller/MultiMethod/List.do"/>">목록요청</a></li>
         <li><a href="<c:url value="/Controller/MultiMethod/Edit.do"/>">수정요청</a></li>
         <li><a href="<c:url value="/Controller/MultiMethod/Delete.do"/>">삭제요청</a></li>
         <li><a href="<c:url value="/Controller/MultiMethod/View.do"/>">상세요청</a></li>				
    </ul>									
</fieldset>

 

OneMethodNoParamController

이거 되게 신기.. 경로가 다 같은데 끝에만 다를 때 { } 요렇게 변수처리를 한다 오오 신기신기!!

이렇게 쓸 땐 그래서

@RequestMapping랑 ~~/{path} 랑 @PathVariable String path 

이 세개가 삼총사 셋트!!!

@Controller
public class OneMethodNoParamController {
	//컨트롤러 메소드 저걸 변수로 만드네.. list,edit,delete,view
	@RequestMapping("/Controller/OneClass/{path}")
	public String noparam(@PathVariable String path,Map map) {
		System.out.println(path);  //.do는 빠진다				
		//데이타 저장
		switch(path.toUpperCase()) {
			case "LIST":map.put("message","목록요청 입니다.");break;
			case "EDIT":map.put("message","수정요청 입니다.");break;
			case "DELETE":map.put("message","삭제요청 입니다.");break;
			default: map.put("message","상세요청 입니다.");break;
		}
		//디스패처 서블릿에게 뷰정보 반환
		return "controller02/Controller";
	}
}

 

 

OneMethodParamController

파라미터가 있을 때!(사용자가 입력하는게 아니라서 쿼리스트링으로 넘김)

@Controller
public class OneMethodParamController {
	//컨트롤러메소드
	@RequestMapping({"/Controller/OneClassParam/List.do","/Controller/OneClassParam/Edit.do",
    			"/Controller/OneClassParam/Delete.do","/Controller/OneClassParam/View.do",})	
    public String param(@RequestParam String crud, Map map) {			
		switch(crud.toUpperCase()) {
			case "READ-LIST":map.put("message","목록요청 입니다.");break;
			case "UPDATE":map.put("message","수정요청 입니다.");break;
			case "DELETE":map.put("message","삭제요청 입니다.");break;
			default: map.put("message","상세요청 입니다.");break;
	  }
		return "controller02/Controller";				
	}
}

 

MultiMethodController

여러개의 컨트롤러 메소드

@Controller
public class MultiMethodController {
	//컨트롤러 메소드(총 4개)
	@RequestMapping("/Controller/MultiMethod/List.do")
	public String list(ModelMap model) {
		//데이터 저장
		model.addAttribute("message","It requests LIST");
		//디스패처 서블릿에게 뷰정보 반환
		return "controller02/Controller" ;
	}

	@RequestMapping("/Controller/MultiMethod/Edit.do")
	public String edit(Model model) {
		//데이터 저장
		model.addAttribute("message","It requests EDIT");
		//디스패처 서블릿에게 뷰정보 반환
		return "controller02/Controller" ;
	}
	
	@RequestMapping("/Controller/MultiMethod/Delete.do")
	public String delete(Map model) {
		//데이터 저장
		model.put("message","It requests DELETE");
		//디스패처 서블릿에게 뷰정보 반환
		return "controller02/Controller" ;
	}
	
	@RequestMapping("/Controller/MultiMethod/View.do")
	public String view(ModelMap model) {
		//데이터 저장
		model.addAttribute("message","It requests VIEW");
		//디스패처 서블릿에게 뷰정보 반환
		return "controller02/Controller" ;
	}
	
}


[뷰]

어느곳으로 뿌려줄지의 정보를 가지고 있는 놈!!

ViewResolver.jsp

<legend class="w-auto px-3">뷰 리졸버</legend>
<h2>Scope : ${requestScope.message} , Parameter : ${param.message }</h2>
<a href="<c:url value="/ViewResolver/ViewResolver.do"/>">InternalResourceViewResolver</a>

 

ViewResolverController

//컨트롤러 클래스
@Controller
public class ViewResolverController {
	
	[컨트롤러 메소드-String타입으로 뷰정보 반환]
	@RequestMapping("/ViewResolver/ViewResolver.do")
	public String execute(Model model) {
		//데이터 저장
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy년 MM월 dd일");
		model.addAttribute("message",dateFormat.format(new Date()));
		
        //뷰 정보 반환		
		//1. .jsp페이지로 forward
        //접두어(/WEB-INF/views/)와 접미어(.jsp)를 뺀 논리적인 이름만 반환
		return "viewresolver03/ViewResolver";
	//	return "viewresolver03/ViewResolver?message=Hello Spring!";    //404에러

		//2. .do로 forward
        // 뷰정보 반환 시 접두어/접미어가 붙어서 404에러 발생 
   //   return "/ViewResolver/Continues.do";   에러남( /WEB-INF/views/ViewResolver/Continues.do.jsp )   */
	
     //[----접두어/접미어 영향 받지 않기 : 주로 .do로 이동 시에 적용한다----]		
 /**** InternalResourceViewResolver를 통한 접두어,접미어에 영향 안받으려면 String 반환 시 
 		forward:나 "redirect:"를 앞에 붙인다	 
		forward:이게 디폴트다. 즉, 포워드방식의 이동이 기본이다	*/
		return "forward:/ViewResolver/Continues.do";		
        
		//[forward 로 이동시]
		//1. .jsp페이지로 forward		
        return "forward:/WEB-INF/views/viewresolver03/ViewResolver.jsp?message=Hello Spring!";		
      				
        //2. .do로 forward
	    return "forward:/ViewResolver/Continues.do?message=Hi Spring!";
		
        //[redirect로 이동시]
	    //※리다이렉트시  모델객체에 저장된 데이터는 쿼리스트링으로 전달된다
		//1. .jsp페이로 redirect- /WEB-INF밑에 있는 JSP파일을 직접 URL로 요청한거와 같다 그래서 404에러
		//return "redirect:/WEB-INF/views/viewresolver03/ViewResolver.jsp";   이건 에러 남 
		return "redirect:/ViewResolver/Continues.do";  // 얘는 대신 스코프영역이 출력 안되지!
	}

	
	[컨트롤러 메소드-ModelAndView타입으로 뷰정보 반환]
	@RequestMapping("/ViewResolver/ViewResolver.do")
	public ModelAndView execute() {
		ModelAndView mav = new ModelAndView();
		//데이터저장
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy년 MM월 dd일");
		mav.addObject("message",dateFormat.format(new Date()));
		
        //[포워드]
		//뷰정보 설정
		mav.setViewName("viewresolver03/ViewResolver");  // ok접두어 접미어 다 잘 붙음
		mav.setViewName("forward:/WEB-INF/views/viewresolver03/ViewResolver.jsp?message=Hello Spring!"); 얘도 잘 됨

		InternalResourceView view = new InternalResourceView();
        mav.setView(view);
		return mav;
	//	view.setUrl("viewresolver03/ViewResolver");//404에러
		view.setUrl("/WEB-INF/views/viewResolver03/ViewResolver.jsp?message=Hello Spring!"); //forward:붙이면 404에러

		//[리다이렉트로 이동]
		//mav.setViewName("redirect:/WEB-INF/views/viewresolver03/ViewResolver.jsp");//404에러
		RedirectView view = new RedirectView();
		view.setUrl("/ViewResolver/Continues.do");
		view.setContextRelative(true);   //위는 상대주소다!!! 라고 설정하게 해줌
		mav.setView(view);
		return mav;
	}
	
  
    (요건 공통)
	@RequestMapping("/ViewResolver/Continues.do")
	public String continues() {		
		return "viewresolver03/ViewResolver";
	}	
}

 

우선 끝 

리턴타입은 다음글에다가 정리해 놓음...