스프링 버젼이 3.1.1로 되어있는데, 4.1.1로 변경하고 저장
lib를 확인해보면 4 버젼으로 업그레이드 된것을 확인 가능하다
파일 위치
JSP와 같은 뷰를 반환하는 것이 아니라 JSON
, XML
같은 데이터를 브라우저로 전송하는 @Restcontroller
를 설정하는 곳이다
package com.myspring.pro29.ex01;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test/*") // /test 밑의 모든 것
public class TestController {
// /hello 로 요청시 브라우저로 문자열을 전송하겠다
@RequestMapping("/hello")
public String hello() {
return "Hello REST!!";
}
}
http://localhost:8700/pro29/test/hello
주소로 값을 요청하면 아래와 같이 설정된 문자열이 표시된다.
F12
를 눌러 관리자 도구를 열고 -> Network
탭을 선택 -> All
클릭 후 F5
로 새로고침 시키면 Content-Type
속성을 확인할 수 있다.
파일 위치
package com.myspring.pro29.ex01;
public class MemberVO {
private String id;
private String pwd;
private String name;
private String email;
// 기본 메소드
public MemberVO() { }
// 회원의 속성 정보를 출력할 것이기 때문에 오버라이드
@Override
public String toString() {
String info = id + "," + pwd + "," + name + "," + email;
return info;
}
// 이하 각 속성에 대한 getter/setter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
JSON 기능을 이용하기 위해서 관련 라이브러리를 추가!
...
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
...
MemberVo의 속성을 JSON으로 변환하여 전송
package com.myspring.pro29.ex01;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
// /test 밑의 모든 것
@RequestMapping("/test/*")
public class TestController {
// /hello 로 요청시 브라우저로 문자열을 전송하겠다
@RequestMapping("/hello")
public String hello() {
return "Hello REST!!";
}
// MemberVO 객체의 속성 값을 저장한 후 JSON으로 전송할 것이다
@RequestMapping("/member")
public MemberVO member() {
MemberVO vo = new MemberVO();
vo.setId("lee");
vo.setPwd("1234");
vo.setName("이자바");
vo.setEmail("java@test.com");
return vo;
}
}
이번에는 http://localhost:8700/pro29/test/member
으로 요청한다. 보이는 값 자체가 아까와는 확실히 다른 모습니다
F12
로 확인해보면 Content-Type
속성 값이 json 임을 확인할 수 있었다.
VO 객체를 만듦 -> josn의 라이브러리(jar) 주입 -> Controller에서 메소드를 만들어 리턴 -> 객체(vo)를 리턴하니까 josn으로 브라우저가 알아서 해석해 보여줌
package com.myspring.pro29.ex01;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
// /test 밑의 모든 것
@RequestMapping("/test/*")
public class TestController {
// /hello 로 요청시 브라우저로 문자열을 전송하겠다
@RequestMapping("/hello")
public String hello() {
return "Hello REST!!";
}
// MemberVO 객체의 속성 값을 저장한 후 JSON으로 전송할 것이다
@RequestMapping("/member")
public MemberVO member() {
MemberVO vo = new MemberVO();
vo.setId("lee");
vo.setPwd("1234");
vo.setName("이자바");
vo.setEmail("java@test.com");
return vo;
}
// 컬렉션(list)로 전달해서 json 배열로(배열 요소는 vo의 자료)
@RequestMapping("/membersList")
public List<MemberVO> listMembers() {
// MemberVo 객체를 저장할 ArrayList 객체를 생성한다
List<MemberVO> list = new ArrayList<MemberVO>();
// MemberVO 객체를 10개 생성해서 ArrayList에 저장
for (int i=0; i<10; i++) {
MemberVO vo = new MemberVO();
vo.setId("lee" + i);
vo.setPwd("1234" + i);
vo.setName("이자바" + i);
vo.setEmail("lee" + i + "@test.com");
list.add(vo);
}
// ArrayList를 JSON으로 브라우저에 전송
return list;
}
}
http://localhost:8700/pro29/test/membersList
요청 시 배열처럼 List의 객체들이 전송된게 보인다
컨텐츠 타입도 json으로 확인 가능
package com.myspring.pro29.ex01;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test/*") // /test 밑의 모든 것
public class TestController {
...
@RequestMapping("/membersMap")
public Map<Integer, MemberVO> membersMap() {
// MemberVO 객체를 저장할 HashMap 객체 생성
Map<Integer, MemberVO> map = new HashMap<Integer, MemberVO>();
// MemberVO 객체를 HashMap에 저장한다
for (int i=0; i<10; i++) {
MemberVO vo = new MemberVO();
vo.setId("kim" + i);
vo.setPwd("3456" + i);
vo.setName("김길동" + i);
vo.setEmail("kim" + i + "@test.com");
map.put(i, vo);
}
return map;
}
}
http://localhost:8700/pro29/test/membersMap
으로 브라우저에게 요청
Map으로 전달한 값이 Josn의 객체 모습으로 나오도록 하는걸 확인.
json에서 name에 해당하는 것은 map의 key값이고, json에서 value에 해당하는 것은 map에서 value로 변환한다 (...?)
package com.myspring.pro29.ex01;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test/*") // /test 밑의 모든 것
public class TestController {
....
@RequestMapping(value= "/notice/{num}", method = RequestMethod.GET)
public int notice(@PathVariable("num") int num) throws Exception {
return num;
}
}
http://localhost:8700/pro29/test/notice/112
이렇게 보내면 112가 num 에 할당된다. 컨텐츠 타입은 당연히 json
근데 만약에
@RequestMapping(value= "/notice/{num}", method = RequestMethod.GET)
public String notice(@PathVariable("num") String s) throws Exception {
return s;
}
이런식으로 작성하면 출력시 String 형식으로 가서 Content-Type: text/html
형식이 된다
브라우저에서 전달되는 josn 데이터를 객체로 자동 변환한다
회원정보 보내기 버튼을 클릭하면, Ajax를 이용해서 회원 정보를 JSON 으로 만들어 컨트롤러로 보낸다
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="EUC-KR" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONTest</title>
<script>
$(function() {
$("#checkJson").click(function() {
// 회원 정보를 json으로 생성
var member = {
id:"kim",
name:"김연아",
pwd:"1234",
email:"kim@test.com" };
$.ajax({
type:"post",
// /test/info 로 요청하기
url:"${contextPath}/test/info",
contentType: "application/json",
// 회원정보를 josn 문자열로 변환
data :JSON.stringify(member),
success:function (data,textStatus){
},
error:function(data,textStatus){
alert("에러가 발생했습니다.");
},
complete:function(data,textStatus){
}
});//end ajax
});
});
</script>
</head>
<body>
<input type="button" id="checkJson" value="회원 정보 보내기" /> <br><br>
<div id="output"></div>
</body>
</html>
@RequestBody
를 이용해 json 데이터를 MemberVO 객체로 자동 변환한다
...
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
static Logger logger = LoggerFactory.getLogger(TestController.class);
@RequestMapping(value ="/info", method = RequestMethod.POST)
// josn으로 전송된 데이터를 MemberVO 객체의 속성에 자동으로 설정
public void modify(@RequestBody MemberVO vo) {
logger.info(vo.toString());
}
...
/pro29로 요청하면 JsonTest.jsp를 표시하도록 설정
package com.myspring.pro29;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "JSONTest";
}
}
요청 주소 http://localhost:8700/pro29/
버튼을 눌러도 화면에 어떤것도 뜨지 않아서 순간 당황했다. 값을 봐야하는건 콘솔인데! 잊고 있었다.
위와 같이 콘솔에 josn으로 회원정보가 전송된 모습을 확인할 수 있다. (버튼을 누르는 횟수만큼 뜬다. 그러니까 여러 개 떠있는건 당황해서 버튼을 연타했었기 때문...)
컨트롤러의 특정 메소드에 달아놓으면 JSP가 아닌 텍스트나 json으로 결과를 전송할 수 있다.
파일 생성
package com.myspring.pro29.ex02;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ResController {
@RequestMapping(value = "/res1")
// 메소드 호출시 데이터를 전송하도록 설정
@ResponseBody
// Map 데이터를 브라우저로 전송
public Map<String, Object> res1() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", "lee");
map.put("name", "이자바");
return map;
}
// 메소드 호출 시 home.jsp를 브라우저로 전송한다
@RequestMapping(value = "/res2")
public ModelAndView res2() {
return new ModelAndView("home");
}
}
처음에 주소로 요청했더니 404 에러가 떠서 당황했다. 알고보니 이전에 사용하던 Controller 파일에 달아줬던 @Controller
를 지워주지 않아서 그런거였고.. 확인 잘하자.
확인 후 다시 요청하니 이렇게 json 식으로 떴다.
그 다음 res2를 요청했더니 수정없이 놔둔 기본의 "home.jsp"가 요청되었다
...
@RequestMapping("membersList2")
public ResponseEntity<List<MemberVO>> listMembers2() {
List<MemberVO> list = new ArrayList<MemberVO>();
for(int i=0; i<10; i++) {
MemberVO vo = new MemberVO();
vo.setId("lee" + i);
vo.setName("이자바" + i);
vo.setPwd("2345" + i);
vo.setEmail("lee" + i + "@test.com");
list.add(vo);
}
// 오류코드 500으로 응답
return new ResponseEntity(list,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
다른 곳에 @controller
가 없는지 유의하자
F12
를 보면 Status가 500인걸 확인할 수 있다
(아래 사진은 이전에 사용했던, status를 설정하지 않은 다른 페이지의 것)
HttpHeaders 클래스를 이용해서 ResponseEntity로 전송할 데이터의 종류와 한글 인코딩을 설정
...
@RequestMapping(value = "/res3")
public ResponseEntity res3() {
HttpHeaders responseHeaders = new HttpHeaders();
// 전송할 데이터의 종류와 인코딩을 설정
responseHeaders.add("Content-Type", "text/html; charset=utf-8");
// 전송할 자바 스크립트 코드를 문자열로 작성
String message = "<script>";
message += " alert('새 회원을 등록하겠습니다.' );";
message += " location.href='/pro29/test/membersList2'; ";
message += "</script>";
// ResponseEntity를 이용해 Html 형식으로 전송
return new ResponseEntity(message, responseHeaders, HttpStatus.CREATED);
}
}
http://localhost:8700/pro29/test/membersList2
아래와 같이 전송된 자바스크립트(의 경고) 메시지가 표시된다.
확인을 누르면 아래와 같이 membersList2의 화면으로 넘어간다