Spring 4 기반의 RESTful Web Service 구현

Slides:



Advertisements
Similar presentations
3. 메소드와 변수 SCJP 자격증 프로젝트 발표자 : 최선웅. 1. 메 소 드 개 념 2. 메 소 드 양 식 3. 메 소 드 변 수 4. 메 소 드 예 제 5. 참 고 문 헌 / 자 료 목 차.
Advertisements

2008 년 11 월 20 일 실습.  실험제목 ◦ 데이터베이스 커넥션 풀  목표 ◦ 데이터베이스 커넥션 풀의 사용.
Nov Youn-Hee Han Term Project 안내 Nov Youn-Hee Han
Spring MVC ㅇ 스프링 MVC 구성요소 설명 DispatcherServlet 클라이언트의 요청을 컨트롤러에게 전달하고
Oozie Web API 기능 테스트 이승엽.
10. 예외 처리.
PARK SUNGJIN Oracle 설치 PARK SUNGJIN
DB 프로그래밍 학기.
DB 프로그래밍 학기.
소리가 작으면 이어폰 사용 권장!.
You YOungseok 데이터베이스 테이블 및 인덱스 You YOungseok.
4강. Servlet 맛보기 Servlet 문서 작성 하기 web.xml에 서블릿 맵핑 어노테이션을 이용한 서블릿 맵핑
질의어와 SQL 기본 SQL 고급 SQL 데이타의 수정 데이타 정의 언어 내장 SQL
Sep Youn-Hee Han 웹서비스 컴퓨팅 수업을 위한 코딩 환경 준비 Sep Youn-Hee Han
제 09 장 데이터베이스와 MySQL 학기 인터넷비즈니스과 강 환수 교수.
JDBC 프로그래밍 이수지 이동주 1.
6장 Mysql 명령어 한빛미디어(주).
(개정판) 뇌를 자극하는 Red Hat Fedora 리눅스 서버 & 네트워크
11장. 데이터베이스 서버 구축과 운영.
IOC, DI 2015 Web Service Computing.
14장 질의응답 한빛미디어(주).
나민영 서경대학교 컴퓨터공학과 CGVR Lab 같이만들어보자 5주차 OpenCV 설정 및 기초.
8.1 인터페이스 개요와 인터페이스 정의 8.2 인터페이스의 사용 8.3 인터페이스의 상속 8.4 인터페이스 참조
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
Lesson 6. 형변환.
ASP.NET : Database 접근 2008 컴퓨터공학실험(Ⅰ)
4-1장. MySQL 제13장.
FTP 프로그램 채계화 박재은 박수민.
16장. 테이블의 변경 새로운 행 삽입 테이블에서 테이블로 행을 복사 행 값의 변경 테이블에서 행 삭제
소프트웨어 분석과 설계 Struts2 & JBOSS 설치하기
8 데이터베이스 사용하기.
12 데이터베이스 사용하기.
KHS JDBC Programming 4 KHS
You YoungSEok Oracle 설치 You YoungSEok
웹 어플리케이션 보안 2016년 2학기 3. Mongo db.
Web Socket.
[INA470] Java Programming Youn-Hee Han
~27 윤형기 Python 프로그래밍 (보충) ~27 윤형기
컴퓨터응용과학부 Java Enterprize(DB) 제 7 주
CHAPTER 06. 데이터베이스 자료의 조직적 집합체_데이터베이스 시스템의 이해
CHAP 13. 방명록 만들기 실습.
Maven 프로젝트 생성 및 JAX-RS (Java API for RESTful Services) 코딩
JDBC Lecture 004 By MINIO.
JSP 게시판 구현.
개발 환경 세팅.
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
Smart Workplace 개발자 가이드
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
USN(Ubiquitous Sensor Network)
SpringFramework 중간고사 요약 REST by SpringFramework.
자바 5.0 프로그래밍.
기말 프로젝트 계획 MVC 패턴 기반 웹 애플리케이션 개발 프로젝트명 : 팀명 : 팀원 :
Internet Computing KUT Youn-Hee Han
15강. 폼 데이터 값 검증 Validator를 이용한 검증 ValidationUtils 클래스
14강. 세션 세션이란? 세션 문법 Lecturer Kim Myoung-Ho Nickname 블스
12강. 컨트롤러 컨트롤러 클래스 제작 요청 처리 메소드 제작 뷰에 데이터 전달
13장 자바빈과 데이터베이스를 연동한 게시판 시스템
STS 또는 Eclipse 에서 프로젝트를 Export 하고 Import 하는 방법
Introduction to JSP & Servlet
테이블 관리 테이블 생성,수정,삭제 데이터 입력 수정, 삭제 2010학년도 2학기.
~27 윤형기 Python 프로그래밍 (보충) ~27 윤형기
뇌를 자극하는 Windows Server 장. 데이터베이스 서버.
다자간 채팅프로그램 김형도 허영민
(Artificial Intelligence, BabyBoom, Contract, BlockChain…)
Stored program 장종원
웹과 모바일 홈페이지의 이해와 제작 [PHP / MYSQL] 게시판 만들기
Data Base Mysql.
 6장. SQL 쿼리.
M.B.TEAM 중간 발표 (5.18) 이 제걸 백 인호.
20 XMLHttpRequest.
Presentation transcript:

Spring 4 기반의 RESTful Web Service 구현 Oct. 2015 Youn-Hee Han LINK@KOREATECH http://link.koreatech.ac.kr

RESTful Server LINK@KOREATECH

Spring 프로젝트 내 pom.xml 수정 REST Web Service 구현을 위한 pom.xml 수정 객체를 XML/JSON로 변환하거나 그 역변환을 위한 라이브러리(의존성) 추가 … <!-- XML and JSON --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.6.2</version> </dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <artifactId>jackson-databind</artifactId> </dependencies> LINK@KOREATECH

웹 서비스 Server 구축 (Spring 기반) Resource 정보 구축 온도 센서 정보를 Resource로 활용 MySQL 활용 Temperature 테이블 내 다음과 같은 정보 저장 온도 센서 HTTP Reqeuest HTTP Response 온도 자원을 활용하는 웹 서비스 Client 온도 자원을 구축하고 있는 자원 서버 + 웹 서비스 Server 구축 (Spring 기반) LINK@KOREATECH

Resource 정보 구축 온도 센서 정보를 Resource로 활용 현재 사용중인 DB 스키마 (예: wsc)에 Temperature 테이블 생성 및 가상 온도 정보 입력 프로젝트 소스 내 다음 파일 참고 src/main/resources/common/rest.sql DROP TABLE IF EXISTS `temperature`; CREATE TABLE `temperature` ( `ID` int(32) unsigned NOT NULL AUTO_INCREMENT, `sensor_id` varchar(45) NOT NULL, `temperature` float NOT NULL, `datetime` datetime NOT NULL, `location` varchar(500) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT INTO `temperature` VALUES (1, 'temp1', 32.4, '2015-05-15 08:18:24', '1st Floor, 4th Engineering Building, KoreaTech'), (2, 'temp2', 34.9, '2015-05-16 08:10:54', '3st Floor, 2th Engineering Building, KoreaTech'); LINK@KOREATECH

Domain 객체 클래스 구성 Temperature 클래스 구성 온도 정보를 담아서 전달시킬 수 있는 기본 클래스 웹 서비스 Server가 Client로 전달할 때 Json 포맷으로 변환됨 프로젝트 소스 내 다음 파일 참고 src/main/java/koreatech/cse/domain/rest/Temperature.java package koreatech.cse.domain.rest; import java.sql.Date; public class Temperature { private int id; private String sensorId; private float temperature; private Date datetime; private String location; public int getId() { return id; } … LINK@KOREATECH

Repository 객체 클래스 구성 MyBatis기반 TemperatureMapper 인터페이스 구성 src/main/java/koreatech/cse/repository/rest/TemperatureMapper.java package koreatech.cse.repository.rest; … @Repository public interface TemperatureMapper { @Insert("INSERT INTO TEMPERATURE (SENSOR_ID, TEMPERATURE, DATETIME, LOCATION) VALUES (#{sensorId}, #{temperature}, #{datetime}, #{location})") @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", before = false, resultType = int.class) void insert(Temperature temperature); @Update("UPDATE TEMPERATURE SET TEMPERATURE = #{temperature}, DATETIME = #{datetime}, LOCATION = #{location} WHERE ID = #{id}") void update(Temperature temperature); @Select("SELECT * FROM TEMPERATURE WHERE ID = #{id}") Temperature findOne(@Param("id") int id); @Delete("DELETE FROM TEMPERATURE WHERE ID = #{id}") void delete(@Param("id") int id); @Select("SELECT * FROM TEMPERATURE WHERE SENSOR_ID = #{sensorId}") Temperature findOneBySensorId(@Param("sensorId") String sensorId); @Select("SELECT * FROM TEMPERATURE WHERE LOCATION LIKE CONCAT('%', #{location}, '%')") List<Temperature> findByLocation(@Param("location") String location); } LINK@KOREATECH

RestController 구성 Spring 4 기반의 RestController 구성 컨트롤러이므로 @RequestMapping 을 활용하여 접근 패스 지정 {Context Root}/thermometer 이전에 생성한 Repository 객체를 @Inject 로 주입받음 프로젝트 소스 내 다음 파일 참조 src/main/java/koreatech/cse/controller/rest/ TemperatureRestController.java package koreatech.cse.controller.rest; … @RestController @RequestMapping("/thermometer") public class TemperatureRestController { @Inject private TemperatureMapper temperatureMapper; … } LINK@KOREATECH

RestController 구성 GET 서비스 – 1 Path: {Context Root}/thermometer/temperature/{sensorId} 센서 아이디를 받아서 해당 센서의 센싱 정보를 JSON 포맷으로 전달 서비스 요청 예 http://localhost:8080/thermometer/temperature/temp1 센서 ID에 해당하는 ‘temp1’은 PathVariable 형태로 활용됨 @Transactional @RequestMapping(value="/temperature/{sensorId}", method=RequestMethod.GET, produces = "application/json") public ResponseEntity<Temperature> temperature(@PathVariable("sensorId") String sensorId) { Temperature temperature = temperatureMapper.findOneBySensorId(sensorId); if (temperature == null) { System.out.println("Temperature sensor with id (" + sensorId + “) is not found"); return new ResponseEntity<Temperature>(HttpStatus.NOT_FOUND); } return new ResponseEntity<Temperature>(temperature, HttpStatus.OK); LINK@KOREATECH

RestController 구성 GET 서비스 – 2 Path: {Context Root}/thermometer/xml/temperature/{sensorId} 센서 아이디를 받아서 해당 센서의 센싱 정보를 XML 포맷으로 전달 서비스 요청 예 http://localhost:8080/thermometer/xml/temperature/temp1 @Transactional @RequestMapping(value="/xml/temperature/{sensorId}", method=RequestMethod.GET, produces="application/xml") public ResponseEntity<Temperature> temperatureXml(@PathVariable("sensorId") String sensorId) { Temperature temperature = temperatureMapper.findOneBySensorId(sensorId); if (temperature == null) { System.out.println("Temperature sensor with id " + sensorId + " is not found"); return new ResponseEntity<Temperature>(HttpStatus.NOT_FOUND); } return new ResponseEntity<Temperature>(temperature, HttpStatus.OK); } LINK@KOREATECH

RestController 구성 GET 서비스 – 3 Path: {Context Root}/thermometer/temperature/location/{location} 센서 위치 정보를 받아서 해당 위치 정보를 지니고 있는 센서들의 센싱 정보를 JSON 포맷으로 전달 서비스 요청 예 http://localhost:8080/thermometer/temperature/location/KoreaTech 위치 정보에 해당하는 ‘KoreaTech’는 PathVariable 형태로 활용됨 @Transactional @RequestMapping(value="/temperature/location/{location}", method=RequestMethod.GET, produces="application/json") public ResponseEntity<List<Temperature>> temperatureByLocation( @PathVariable("location") String location) { List<Temperature> temperatureList = temperatureMapper.findByLocation(location); if (temperatureList.size() == 0) { System.out.println("Temperature sensors with location of " + location + " are not found"); return new ResponseEntity<List<Temperature>>(HttpStatus.NOT_FOUND); } return new ResponseEntity<List<Temperature>>(temperatureList, HttpStatus.OK); LINK@KOREATECH

RestController 구성 GET 서비스 – 4 Path: {Context Root}/thermometer/xml/temperature/location/{location} 센서 위치 정보를 받아서 해당 위치 정보를 지니고 있는 센서들의 센싱 정보를 XML 포맷으로 전달 서비스 요청 예 http://localhost:8080/thermometer/xml/temperature/location/KoreaTech @Transactional @RequestMapping(value="/xml/temperature/location/{location}", method=RequestMethod.GET, produces="application/xml") public ResponseEntity<List<Temperature>> temperatureByLocationXml( @PathVariable("location") String location) { List<Temperature> temperatureList = temperatureMapper.findByLocation(location); if (temperatureList.size() == 0) { System.out.println("Temperature sensors with location of " + location + " are not found"); return new ResponseEntity<List<Temperature>>(HttpStatus.NOT_FOUND); } return new ResponseEntity<List<Temperature>>(temperatureList, HttpStatus.OK); } LINK@KOREATECH

RestController 구성 POST 서비스 (Create a Temperature Resource) Path: {Context Root}/temperature 새로운 센서 정보를 서버의 자원으로 생성 @Transactional @RequestMapping(value = "/temperature/", method = RequestMethod.POST) public ResponseEntity<Void> createTemperature(@RequestBody Temperature temperature, UriComponentsBuilder ucBuilder) { if (temperatureMapper.findOneBySensorId(temperature.getSensorId()) != null) { System.out.println("A temperature sensor with id (" + temperature.getSensorId() + ") already exists"); return new ResponseEntity<Void>(HttpStatus.CONFLICT); } temperatureMapper.insert(temperature); HttpHeaders headers = new HttpHeaders(); headers.setLocation( ucBuilder.path("/temperature/{sensorId}").buildAndExpand(temperature.getSensorId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); LINK@KOREATECH

RestController 구성 PUT 서비스 (Update a Temperature Resource) Path: {Context Root}/temperature/{sensorId} 기존 센서 정보를 업데이트 @Transactional @RequestMapping(value = "/temperature/{sensorId}", method = RequestMethod.PUT) public ResponseEntity<Void> updateTemperature(@PathVariable("sensorId") String sensorId, @RequestBody Temperature temperature) { Temperature storedTemperature = temperatureMapper.findOneBySensorId(sensorId); if (storedTemperature == null) { System.out.println("No temperature sensor with id (" + sensorId + " not found"); return new ResponseEntity<Void>(HttpStatus.NOT_FOUND); } storedTemperature.setTemperature(temperature.getTemperature()); storedTemperature.setLocation(temperature.getLocation()); storedTemperature.setDatetime(temperature.getDatetime()); temperatureMapper.update(storedTemperature); return new ResponseEntity<Void>(HttpStatus.OK); LINK@KOREATECH

RestController 구성 DELETE 서비스 (Delete a Temperature Resource) Path: {Context Root}/temperature/{sensorId} 기존 센서 정보를 삭제 @Transactional @RequestMapping(value = "/temperature/{sensorId}", method = RequestMethod.DELETE) public ResponseEntity<Temperature> deleteTemperature(@PathVariable("sensorId") String sensorId) { Temperature storedTemperature = temperatureMapper.findOneBySensorId(sensorId); if (storedTemperature == null) { System.out.println("No temperature sensor with id (" + sensorId + " not found"); return new ResponseEntity<Temperature>(HttpStatus.NOT_FOUND); } temperatureMapper.delete(storedTemperature.getId()); return new ResponseEntity<Temperature>(HttpStatus.NO_CONTENT); LINK@KOREATECH

RESTful Client LINK@KOREATECH

RestClient 생성 Spring 4에서 지원하는 RestTemplate 클래스 활용 서버와 별개의 프로젝트로서 구성 org.springframework.web.client.RestTemplate 서버와 별개의 프로젝트로서 구성 콘솔창에서 임의의 폴더로 이동하여 아래 명령어 수행 새로운 프로젝트 폴더 (restful_client)를 IntelliJ 프로젝트로서 등록 mvn archetype:generate -DgroupId=koreatech.link -DartifactId=restful_client -Dpackage=koreatech.cse.rest.client -Dversion=1.0

Spring 프로젝트 내 pom.xml 수정 RestTemplate 활용을 위한 라이브러리(의존성) 추가 … <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.1.RELEASE</version> </dependency> </dependencies> LINK@KOREATECH

Spring 프로젝트 내 pom.xml 수정 객체를 XML/JSON로 변환하거나 그 역변환을 위한 라이브러리(의존성) 추가 … <!-- XML and JSON --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.6.2</version> </dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <artifactId>jackson-databind</artifactId> </dependencies> LINK@KOREATECH

Domain 객체 클래스 구성 Temperature 클래스 구성 온도 정보를 담아서 전달시킬 수 있는 기본 클래스 클라이언트 프로젝트 소스 내 다음 파일 참고 src/main/java/koreatech/cse/rest/client/domain/Temperature.java package koreatech.cse.rest.client.domain; import java.sql.Date; public class Temperature { private int id; private String sensorId; private float temperature; private Date datetime; private String location; public int getId() { return id; } … LINK@KOREATECH

Domain 객체 클래스 구성 Temperature 클래스내에 toString() 구성 IntelliJ의 코드 자동 생성 기능 사용 서버로 부터 받은 온도 정보 객체를 클라이언트에서 출력하기 위한 목적 @Override public String toString() { return "Temperature{" + "id=" + id + ", sensorId='" + sensorId + '\'' + ", temperature=" + temperature + ", datetime=" + datetime + ", location='" + location + '\'' + '}'; } LINK@KOREATECH

Domain 객체 클래스 구성 Temperature 클래스내에 toString() 구성 IntelliJ의 코드 자동 생성 기능 사용 서버로 부터 받은 온도 정보 객체를 클라이언트에서 출력하기 위한 목적 @Override public String toString() { return "Temperature{" + "id=" + id + ", sensorId='" + sensorId + '\'' + ", temperature=" + temperature + ", datetime=" + datetime + ", location='" + location + '\'' + '}'; } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 Spring 4 기반의 RestTemplate 활용 서버의 기본 URI 지정 package koreatech.cse.rest.client; import koreatech.cse.rest.client.domain.Temperature; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import java.net.URI; import java.util.Date; import java.util.List; public class App { public static final String REST_SERVICE_URI = "http://localhost:8080/thermometer"; … } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 GET 서비스 요청 – 1 private static void getTemperature() { System.out.println("Testing GET METHOD (1)----------"); RestTemplate restTemplate = new RestTemplate(); try { ResponseEntity<Temperature> temperatureResponseEntity = restTemplate.getForEntity(REST_SERVICE_URI + "/temperature/temp1", Temperature.class); Temperature temperature = temperatureResponseEntity.getBody(); System.out.println(temperature); } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 GET 서비스 요청 – 2 private static void getTemperatureXml() { System.out.println("Testing GET METHOD (2)----------"); RestTemplate restTemplate = new RestTemplate(); try { ResponseEntity<Temperature> temperatureResponseEntity = restTemplate.getForEntity(REST_SERVICE_URI + "/xml/temperature/temp1", Temperature.class); Temperature temperature = temperatureResponseEntity.getBody(); System.out.println(temperature); } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 GET 서비스 요청 – 3 private static void getTemperatureByLocation() { System.out.println("Testing GET METHOD (3)----------"); RestTemplate restTemplate = new RestTemplate(); try { ResponseEntity<List> listResponseEntity = restTemplate.getForEntity(REST_SERVICE_URI + "/temperature/location/KoreaTech", List.class); List<Temperature> temperatureList = listResponseEntity.getBody(); for (int i = 0; i < temperatureList.size(); i++) { System.out.println(temperatureList.get(i)); } } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 GET 서비스 요청 – 4 private static void getTemperatureByLocationXml() { System.out.println("Testing GET METHOD (4)----------"); RestTemplate restTemplate = new RestTemplate(); try { ResponseEntity<List> listResponseEntity = restTemplate.getForEntity(REST_SERVICE_URI + "/xml/temperature/location/KoreaTech", List.class); List<Temperature> temperatureList = listResponseEntity.getBody(); for (int i = 0; i < temperatureList.size(); i++) { System.out.println(temperatureList.get(i)); } } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 POST 서비스 요청 private static void createTemperature() { System.out.println("Testing POST METHOD----------"); RestTemplate restTemplate = new RestTemplate(); Temperature temperature = new Temperature(); temperature.setSensorId("temp3"); temperature.setTemperature((float)37.0); temperature.setDatetime(new Date()); temperature.setLocation("2nd Floor, 4th Engineering Building, KoreaTech"); try { URI uri = restTemplate.postForLocation( REST_SERVICE_URI + "/temperature/", temperature, Temperature.class); System.out.println("Location : " + uri.toString()); } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 PUT 서비스 요청 private static void updateTemperature() { System.out.println("Testing PUT METHOD----------"); RestTemplate restTemplate = new RestTemplate(); Temperature temperature = new Temperature(); temperature.setSensorId("temp1"); temperature.setTemperature((float)31.1); temperature.setDatetime(new Date()); temperature.setLocation("1st Floor, 4th Engineering Building, KoreaTech"); try { restTemplate.put(REST_SERVICE_URI + "/temperature/temp1", temperature); System.out.println("PUT METHOD - SUCCESS!"); } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } LINK@KOREATECH

RESTful Client – CRUD 요청 코드 DELETE 서비스 요청 private static void deleteTemperature() { System.out.println("Testing DELETE METHOD----------"); RestTemplate restTemplate = new RestTemplate(); try { restTemplate.delete(REST_SERVICE_URI + "/temperature/temp2"); System.out.println("DELETE METHOD - SUCCESS!"); } catch (HttpClientErrorException e) { System.out.println(e.getStatusCode() + ": " + e.getStatusText()); } LINK@KOREATECH

크롬 앱을 활용한 Rest Client 테스트 Advanced Rest Client 크롬 앱 활용 LINK@KOREATECH

크롬 앱을 활용한 Rest Client 테스트 GET 요청 테스트 LINK@KOREATECH

크롬 앱을 활용한 Rest Client 테스트 POST 요청 테스트 LINK@KOREATECH

크롬 앱을 활용한 Rest Client 테스트 PUT 요청 테스트 LINK@KOREATECH

크롬 앱을 활용한 Rest Client 테스트 DELETE 요청 테스트 LINK@KOREATECH