spring 4강 Controller와 View의 연결 방법
@Controller 어노테이션을 쓴 클래스는 개발자가 객체를 관리할 수 없다.
컨트롤러의 객체는 스프링 프레임워크가 관리한다.
view/include/header.jsp
1 2 3 4 5 6 7 8 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <c:set var="path" value="${pageContext.request.contextPath}" /> <script src="http://code.jquery.com/jquery-3.3.1.min.js"> </script> | cs |
header.jsp는 모든 페이지에 include 시킬 예정 (모든 페이지에 포함되는 코드)
위 태그라이브러리를 쓰기위해서 JSP에선 jstl.jar을 다운받아 톰캣 라이브러리에 추가해야했지만
메이븐 프로젝트에서는 pom.xml에 작성만 하면된다.
view/include/menu.jsp
WEB-INF 하위에 있으므로 직접 실행이 불가능하고 클래스를 경유하여 실행할 수 있다.
header와 menu 페이지를 include 시킨 test.jsp페이지 생성
test.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <%@ include file="include/header.jsp" %> <script> function doF(){ $.ajax({ type: "post", url: "${path}/test/doF", success: function(result){ $("#result").html( "상품명:"+result.name+",가격:"+result.price); } }); } </script> </head> <body> <%@ include file="include/menu.jsp" %> <h2>링크 테스트</h2> <a href="${path}/test/doA">doA</a><br> <a href="${path}/test/doB">doB</a><br> <a href="${path}/test/doC">doC</a><br> <a href="${path}/test/doD">doD</a><br> <a href="javascript:doF()">doF</a><br> <div id="result"></div> </body> </html> | cs |
{path}는 Controller에서 리턴받거나 RequestMapping으로 받은 url인데
생략된 경로는 servlet-context에 설정돼있다.
Controller를 경유하여 실행한 화면
src/main/java > com.example.spring01.controller>MainController.java 생성
HomeController 대신 MainController로 실행하기위해 HomeController.java - home메서드를 막아준다
메서드 상단 @RequestMapping(value="/", method=RequestMethod.GET) 만 주석처리해주면 된다.
컨트롤러 클래스는 반드시 클래스명 상단에 @Controller 어노테이션을 추가해줘야한다.
그래야만 서버가 실행될 때 해당 클래스가 자동으로 메모리에 올라간다.
MainController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //컨트롤러 어노테이션(컨트롤러 객체를 자동으로 생성) @Controller public class MainController { // 로그 객체 생성 private static final Logger logger = LoggerFactory.getLogger(MainController.class); // 시작 페이지로 이동 @RequestMapping("/") // url pattern mapping public String main(Model model) { //JSP 서블릿 클래스는 doGet doPost 메서드가 존재했는데 여기서 model이 그 역할을 한다. // Model : 데이터를 담는 그릇 역할, map 구조로 저장됨// key와 value로 구성 // model.addAttribute("변수명", 값) model.addAttribute("message", "홈페이지 방문을 환영합니다."); // <beans:property name="prefix" value="/WEB-INF/views/" /> // <beans:property name="suffix" value=".jsp" /> // /WEB-INF/views/main.jsp return "main"; // main.jsp로 포워딩됨 //JSP에서 dispatcher 객체로 forward한것과 같은 역할 //나머지 경로는 spring > appServlet > servlet-context.xml에 설정돼있음 //컨트롤러에 대한 설정은 서블릿컨텍스트에 있다. }//>> main.jsp를 컨트롤 클래스를 경유하여 실행한다. | cs |
URL name과 jsp페이지이름이 같으면 리턴값으로 페이지 주소를 주지 않아도되고
@RequestMapping(" ... ")에 입력된 곳으로 이동한다.
단, 리턴하지 않으므로 model 에 데이터를 담아 보낼 수도 없다.
위 URL이 .do로 끝날 경우 @RequestMapping( "~.do" ) 이하의 메서드가 실행되고,
그 메서드가 (.do가 빠진)페이지 이름을 리턴하는 식( 리턴하는 경로로 model을 포워드 )
1 2 3 4 | @RequestMapping("test") public void test() { } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 | @RequestMapping("test/doC") public ModelAndView doC() { // Model (넘길 데이터 객체)과 View(넘길 페이지) 함께 처리하는 doC() 메서드 Map<String,Object> map=new HashMap<>(); map.put("product", new ProductDTO("샤프",1000)); //test/doC라는 jsp페이지로 갈 것, //"map"이라는 변수명에 //map(위에서 생성한 해시맵) 객체 담아 보내기 return new ModelAndView("test/doC","map",map); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @RequestMapping("test/doA") public String doA(Model model) { logger.info("doA called..."); model.addAttribute("message","홈페이지 방문을 환영합니다."); return "test/doB"; //forward //URL : http://localhost:8090/spring01/test/doA //보여지는 페이지 : doB 페이지 } @RequestMapping("test/doD") public String doD() { return "redirect:/test/doE"; //redirct는 주소가 바뀐다. //URL : http://localhost:8090/spring01/test/doE //보여지는 페이지 : doE 페이지 } @RequestMapping("test") public void test() { //URL : http://localhost:8090/spring01/test.do //.do는 menu.jsp에서 설정 //보여지는 페이지 : test페이지. URL이름과 페이지이름이 같으면 void로 처리해도 o.k. //리턴값이 없으면 URL에 있는 페이지명을 읽어와서 페이지를 띄운다. } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | <script> function doF(){ $.ajax({ type: "post", url: "${path}/test/doF", success: function(result){ $("#result").html( "상품명:"+result.name+",가격:"+result.price); } }); } </script> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.example.spring01.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.example.spring01.model.dto.ProductDTO; @RestController // 스프링 4.0부터 사용 가능 public class SampleRestController { @ResponseBody // json 형식으로 리턴 @RequestMapping("test/doF") // url mapping public ProductDTO doF() { //호출한 곳으로 데이터가 넘어감(json 형식) return new ProductDTO("냉장고",500000); } } | cs |
@RestController는 스프링 4.0부터 지원되기 때문에 이 전 버전에서는
@Controller를 사용하고 @ResponseBody를 생략해서는 안된다.
test.jsp에서 doF()함수 호출 > SampleRestController.java의 리턴값을 함수doF() 블럭 안의 result가 받는다.
result는 String 형밖에 받지 못하는데 SampleRestController가 리턴하는 값은 ProductDTO타입이므로
ProductDTO를 Json형식 ( {"name":"냉장고", "price":"500000"} ) String타입으로 변환해야한다.
메서드에 @ResponseBody가 적용된 경우, 리턴 객체를 JSON과 XML과 같은 알맞은 응답으로 변환한다.
이 때, 다른 데이터 타입을 json 형식의 String 타입으로 변환해주는 것이 jackson-databind 라이브러리
mvn.repository.com에서 라이브러리 코드 가져오기(groupID와 artitactId 확인)
pom.xml
1 2 3 4 5 6 7 | <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> | cs |
(라이브러리 추가한 것 외에 바뀐게 없는데 이유없이 에러나면
글의 [ 에러 해결 방법 ] 정리해놓은 대로 실행해본다)
'Spring > study' 카테고리의 다른 글
JUnit Test 정리 (0) | 2019.05.30 |
---|---|
컨텍스트( context ) (0) | 2019.05.30 |
spring 3강 로깅, 데이터베이스 연결 테스트 (0) | 2019.05.28 |
spring 2강 스프링의 실행 과정 / 디렉토리 구조 / 주요 특징 (0) | 2019.05.28 |
Spring 1강 개발 환경설정 (0) | 2019.05.27 |