티스토리 뷰
| REST API ?
API : Application Programming Interface
- 개방 interface
- OPEN API와 함께 거론되는 기술이 REST이며, 대부분의 OPEN API는 REST 방식 지원
REST : Representational State Transfer
- 하나의 URI는 하나의 고유한 리소스를 대표하도록 설계
- Resource + HTTP Method (CRUD 처리)
- URI + GET / POST / PUT / DELETE
* 기존 Service에서는 적합한 View를 Client에 전달했다면,
REST Service는 JSON/XML 형식의 data만 전달
* 암묵적인 표준
- 하이픈(-)은 사용 가능하지만 언더바(_)는 사용 X
- 특별한 경우를 제외하고 대문자 사용 X (대소문자 구분)
- URI 마지막에 슬래시(/) 사용 X
- 슬래시(/)로 계층 관계 표현
- 확장자가 포함된 파일 이름을 직접 포함 X
- URI는 명사를 사용
ㅇ 기존 웹 접근 방식
작업 | method |
방식 |
|
Create (Insert) | POST |
/write.do?id=cristoval | 글쓰기 |
Read (Select) | GET |
/view.do?id=cristoval&no=35 | 글읽기 |
Update (Update) | POST |
/modify.do?id=cristoval | 글수정 |
Delete (Delete) | GET |
/delete.do?id=cristoval &no=35 | 글삭제 |
ㅇ REST API 접근 방식
작업 | method | 방식 | |
Create (Insert) | POST | /blog/cristoval | 글쓰기 |
Read (Select) | GET | /blog/cristoval/35 | 글읽기 |
Update (Update) | POST | /blog/cristoval | 글수정 |
Delete (Delete) | GET | /blog/cristoval/35 | 글삭제 |
|| jackson-databind Library
jackson-databind 라이브러리 추가
1 2 3 4 5 6 | <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.3</version> </dependency> | cs |
||| annotaion
@annotation
- @RestController : Controller가 REST 방식을 처리하기 위한 것임을 명시
- @ResponseBody : JSP 같은 View로 전달되는 것이 아닌 데이터 자체를 전달
- @PathVariable : URL 경로에 있는 값을 파라미터로 추출
- @CrossOrigin : Ajax의 크로스 도메인 문제 해결
- @RequestBody : JSON 데이터를 원하는 타입으로 바인딩
||| annotaion Test
@ResponseBody
@PathVariable
1 2 3 4 | @GetMapping("/rest/{id}/{no}") public @ResponseBody String test(@PathVariable String id, @PathVariable int no) { return "Hello Rest " + id + ", " + no; } | cs |
@ResponseBody
1 2 3 4 5 | @GetMapping("/rest2") public @ResponseBody List<String> test2() { List<String> list = Arrays.asList("Hello", "Java", "World"); return list; } | cs |
@ResponseBody
1 2 3 4 | @GetMapping("/restuser") public @ResponseBody UserInfo restuser() { return new UserInfo("cristoval", "jihun", "1234"); } | cs |
위와 같이 브라우저에 json 형태로 출력하는 방법은
Chrome 확장 프로그램에서 JSON Formatter 혹은 유사한 확장 프로그램을 추가해주면 된다.
@RestController로 등록을 해두면
해당 Controller의 메서드들은 자동적으로 @ResponseBody가 적용된다.
return으로 JSP 같은 View로 전달되는 것이 아닌 데이터 자체를 전달
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @RestController @RequestMapping("/rest/user") public class UserRestController { @Autowired UserService service; @GetMapping("/{userId}") public UserInfo selectUser(@PathVariable String userId) { return service.select(userId); } @GetMapping public List<UserInfo> selectAll() { return service.getList(); } } | cs |
| REST API 적용
/src/main/webapp/WEB-INF/views/user/list.jsp
에서 회원 목록을 조회, 등록, 수정, 삭제를 해보려고 한다.
모든 javascript는 $(document).ready(function() { .. } 에서 이루어진다.
Controller는
src/main/java/com/cristoval/member/controller/AdminController.java
에서 이루어진다.
1 2 3 4 5 6 7 8 9 10 | @RestController @RequestMapping("/admin") public class AdminController { @Autowired private UserService userService; // ... } | cs |
||| 회원 정보 조회
list.jsp가 실행되면 전체 회원 목록을 출력해준다.
url는 ${root}/admin/user 로, Get method, dataType은 json으로 해준다.
ajax의 동작이 성공하면 makeList()를 호출해서 users 정보를 출력해준다.
/src/main/webapp/WEB-INF/views/user/list.jsp
1 2 3 4 5 6 7 8 9 10 11 12 | $.ajax({ url:'${root}/admin/user', type:'GET', contentType:'application/json;charset=utf-8', dataType:'json', success:function(users) { makeList(users); }, error:function(xhr,status,msg){ console.log("상태값 : " + xhr.status + " Http에러메시지 : "+ xhr.responseText); } }); | cs |
@GetMapping 대신 아래와 같이 표현할 수도 있다.
@RequestMapping(value = "/user", method = RequestMethod.GET, headers = { "Content-type=application/json" })
headers가 "Content-type=application/json"로 되어있으므로 header로 json이 넘어와야 한다.
src/main/java/com/cristoval/member/controller/AdminController.java
1 2 3 4 | @GetMapping(value = "/user", headers = { "Content-type=application/json" }) public List<MemberDto> userList() { return userService.userList(); } | cs |
//
class가 view인 table tr 에서 더블클릭 이벤트가 발생하면
아래 javascript ajax가 동작하고 회원 상세 정보를 Modal에 출력한다.
userid가 계층에 포함된다.
/src/main/webapp/WEB-INF/views/user/list.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $(document).on("dblclick", "tr.view", function() { let vid = $(this).attr("data-id"); $.ajax({ url:'${root}/admin/user/' + vid, type:'GET', contentType:'application/json;charset=utf-8', success:function(user) { $("#vid").text(user.userid); $("#vname").text(user.username); $("#vemail").text(user.email); $("#vaddress").text(user.address); $("#vjoindate").text(user.joindate); $("#userViewModal").modal(); }, error:function(xhr,status,msg){ console.log("상태값 : " + status + " Http에러메시지 : "+msg); } }); }); | cs |
@PathVariable annotation으로 경로상에 있는 변수를 얻어올 수 있다.
src/main/java/com/cristoval/member/controller/AdminController.java
1 2 3 4 5 | @GetMapping(value = "/user/{userid}", headers = { "Content-type=application/json" }) public MemberDto userInfo(@PathVariable String userid) { // @PathVariable : 경로상에 있는 변수를 얻어오기 return userService.userInfo(userid); } | cs |
||| 회원 등록
등록 버튼이 눌리면, 작성된 dto 데이터를 JSON 형식으로 넘겨준다.
DB에 변경이 일어나므로 POST method로 전달한다.
* modal은 textarea에 데이터가 남아있으므로 line 16~21. 처럼 공백으로 다시 채워주어야 한다.
/src/main/webapp/WEB-INF/views/user/list.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 | $("#registerBtn").click(function() { let registerinfo = JSON.stringify({ "username" : $("#username").val(), "userid" : $("#userid").val(), "userpwd" : $("#userpwd").val(), "email" : $("#email").val(), "address" : $("#address").val() }); $.ajax({ url:'${root}/admin/user', type:'POST', contentType:'application/json;charset=utf-8', dataType:'json', data: registerinfo, success:function(users) { $("#username").val(''); $("#userid").val(''); $("#userpwd").val(''); $("#email").val(''); $("#address").val(''); $("#userRegModal").modal("hide"); makeList(users); }, error:function(xhr,status,msg){ console.log("상태값 : " + status + " Http에러메시지 : "+msg); } }); }); | cs |
@RequestBody annotation으로 JSON 데이터를 Dto Type으로 받아온다.
회원 등록 후 전체 회원 정보를 출력해주어야 하므로 List<MemberDto> 형태의 json이 return
src/main/java/com/cristoval/member/controller/AdminController.java
1 2 3 4 5 | @PostMapping(value = "/user", headers = { "Content-type=application/json" }) public List<MemberDto> userRegister(@RequestBody MemberDto memberDto) { userService.userRegister(memberDto); return userService.userList(); } | cs |
||| 회원 정보 수정
회원 수정 버튼을 click하면 수정 화면에 해당하는 <tr>이 보여진다.
회원 정보 수정이 실행되면 PUT method로 전달된다.
/src/main/webapp/WEB-INF/views/user/list.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 33 34 35 36 37 | // 회원 정보 수정 $(document).on("click", ".modiBtn", function() { let mid = $(this).parents("tr").attr("data-id"); $("#view_" + mid).css("display", "none"); $("#mview_" + mid).css("display", ""); }); // 회원 정보 수정 실행 $(document).on("click", ".modifyBtn", function() { let mid = $(this).parents("tr").attr("data-id"); let modifyinfo = JSON.stringify({ "userid" : mid, "userpwd" : $("#userpwd" + mid).val(), "email" : $("#email" + mid).val(), "address" : $("#address" + mid).val() }); $.ajax({ url:'${root}/admin/user', type:'PUT', contentType:'application/json;charset=utf-8', dataType:'json', data: modifyinfo, success:function(users) { makeList(users); }, error:function(xhr,status,msg){ console.log("상태값 : " + status + " Http에러메시지 : "+msg); } }); }); // 회원 정보 수정 취소 $(document).on("click", ".cancelBtn", function() { let mid = $(this).parents("tr").attr("data-id"); $("#view_" + mid).css("display", ""); $("#mview_" + mid).css("display", "none"); }); | cs |
@RequestBody annotation으로 JSON 데이터를 Dto Type으로 받아온다.
회원 수정 후 전체 회원 정보를 출력해주어야 하므로 List<MemberDto> 형태의 json이 return
src/main/java/com/cristoval/member/controller/AdminController.java
1 2 3 4 5 | @PutMapping(value = "/user", headers = { "Content-type=application/json" }) public List<MemberDto> userModify(@RequestBody MemberDto memberDto) { userService.userModify(memberDto); return userService.userList(); } | cs |
||| 회원 정보 삭제
회원 삭제 버튼이 눌리면,
삭제할 회원의 아이디가 DELETE method로 전달된다.
/src/main/webapp/WEB-INF/views/user/list.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $(document).on("click", ".delBtn", function() { if(confirm("정말 삭제?")) { let delid = $(this).parents("tr").attr("data-id"); $.ajax({ url:'${root}/admin/user/' + delid, type:'DELETE', contentType:'application/json;charset=utf-8', dataType:'json', success:function(users) { makeList(users); }, error:function(xhr,status,msg){ console.log("상태값 : " + status + " Http에러메시지 : "+msg); } }); } }); }); | cs |
@PathVariable annotation으로 경로상에 있는 변수를 얻어올 수 있다.
회원 삭제 후 전체 회원 정보를 출력해주어야 하므로 List<MemberDto> 형태의 json이 return
src/main/java/com/cristoval/member/controller/AdminController.java
1 2 3 4 5 | @DeleteMapping(value = "/user/{userid}", headers = { "Content-type=application/json" }) public List<MemberDto> userDelete(@PathVariable("userid") String userid) { userService.userDelete(userid); return userService.userList(); } | cs |
'Web > Spring' 카테고리의 다른 글
[Spring-Boot] 기본 설정(Spring Starter Project) (4) | 2020.10.27 |
---|---|
[Spring] Swagger를 이용한 REST API 문서화를 해보자! (0) | 2020.10.27 |
[Spring-myBatis] Spring-myBatis Business Logic 구현을 해보자! (0) | 2020.10.23 |
[Spring] 단위 테스트(spring-test, JUnit) (0) | 2020.10.23 |
[Spring-myBatis] Spring-myBatis 프로젝트를 만들어보자 ! (0) | 2020.10.23 |