A 태그 Controller - A taegeu Controller

  • 이 문서는 구루비에서 작성하였습니다.
  • 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
  • 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=10846251&
  • 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.

커스텀 태그를 이용한 Page Controller 예제

EmpRegisterForm.jsp에 사원목록 정보를 추가해 보자

  • <s:action name="list" executeResult="true" /> 소스를 맨 아래 추가해 보자

<%@ page language="java" isELIgnored="false" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c"   uri="http: %>
<%@ taglib prefix="s"   uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "->
<html lang="ko">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">

<script type="text/javascript" language="JavaScript">
	function showMessage(msg){
	    if(msg != ''){
	        alert(msg); 
	    }   
	}

    function insertAct(){    
        var f = document.form;        
        if (!!f.empno.value && !!f.ename.value && !!f.job.value) {
            f.action = "/emp/register.do";
            f.submit();            
        }else {
            alert("input value");
        }
    }

    function listAct(){
        location.href="/emp/list.do";
    }
</script>
</head>
<body onload="showMessage('${msg}');">
<h2><s:text name="emp.success" /></h2>
<form name="form" method="post" action="">
  <table width="280" border="0">
    <tr>
      <td align="right" width="80"> empno : </td>
      <td width="200"><input type="text" id="empno" name="emp.empno" value="${emp.empno}" maxlength="20" size="20"/></td>
    </tr>            
    <tr>
     <td align="right"> ename : </td>
      <td><input type="text" id="ename" name="emp.ename" value="${emp.ename}" maxlength="20" size="20"/></td>
    </tr>
    <tr>
      <td align="right"> job : </td>
      <td><input type="text" id="job" name="emp.job" value="${emp.job}" maxlength="20" size="20"/></td>
    </tr>
    <tr>
      <td align="right"> sal : </td>
      <td><input type="text" id="sal" name="emp.sal" value="${emp.sal}" maxlength="20" size="20"/></td>
    </tr>
    <tr>
      <td align="right"> deptno : </td>
      <td>
        <select name="emp.deptno">
          <option value="10" <c:if test="${emp.deptno==10}">selected</c:if>>10</option>
          <option value="20" <c:if test="${emp.deptno==20}">selected</c:if>>20</option>
          <option value="30" <c:if test="${emp.deptno==30}">selected</c:if>>30</option>
        </select>
      </td>
    </tr>
    <tr>
      <td align="center" colspan="2">
          <input type="button" value="저장" onclick="insertAct()"/> 
          <input type="button" value="취소" onclick="listAct()"/>
      </td>
    </tr>
  </table>
   
 <s:action name="list" executeResult="true" />                                
 
</form>
</body>
</html>

테스트를 진행한다.

  • 사원정보 등록 폼 으로 접속한다. : http://struts2.apache.org/emp/registerForm.do
  • 아래와 같이 사원 목록이 정상적으로 조회되는지 확인해 보자

A 태그 Controller - A taegeu Controller

문서정보

  • 이 문서는 구루비에서 작성하였습니다.
  • 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
  • 출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=10846251&
  • 구루비 지식창고의 모든 문서는 크리에이티브 커먼즈의 저작자표시-비영리-동일조건변경허락(BY-NC-SA) 라이선스에 따라 자유롭게 사용할 수 있습니다.

spring 4강 Controller와 View의 연결 방법

@Controller 어노테이션을 쓴 클래스는 개발자가 객체를 관리할 수 없다.

컨트롤러의 객체는 스프링 프레임워크가 관리한다.

view/include/header.jsp

<%@ 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

<%@ page language="java" contentType="text/html; charset=UTF-8

pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

//request로 받은 contextPath를 path라는 변수에 넣는 jstl태그

<c:set var="path" value="${pageContext.request.contextPath}" />

<div style="text-align: center;">

<a href="${path}/">main</a>

<a href="${path}/gugu.do?dan=7">구구단</a>

<a href="${path}/test.do">테스트</a>

<a href="${path}/member/list.do">회원관리</a>

</div>

<hr>

cs

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을 포워드 )

@RequestMapping("test")

public void test() {

}

cs

페이지 주소를 리턴하면서 객체를 함께 넘기는 방법

리턴타입 : ModelAndView

@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

forward와 redirect의 차이

리턴은 보여줄 페이지를 결정하는데 

forward 방식은 주소값이 @RequestMapping(" ... ") //...이면 하단 메서드 실행

... 그대로 유지된 채로 리턴한 페이지를 보여주고

리다이렉트는 리턴한 페이지의 주소와 페이지를 보여준다. 

(주소가 바뀐다. @RequestMapping(" ... ")의 ...과 다른 주소로 이동할 수 있다.)

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

Ajax 처리 전용 컨트롤러 (백그라운드에서 실행됨)

test.jsp 일부

<script>

function doF(){

$.ajax({

type: "post",

url: "${path}/test/doF",

success: function(result){

$("#result").html(

"상품명:"+result.name+",가격:"+result.price);

}

});

}

</script>

cs

SampleRestController.java

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 확인)

Jackson Databind » 2.9.8

pom.xml

<!-- 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 개발 환경설정 

 글의 [ 에러 해결 방법 ] 정리해놓은 대로 실행해본다)