프로필사진
RESTful(9) - @RequestEntity, RestTemplate 사용하기

2020. 5. 12. 11:09🔴 Spring

300x250

@RequestEntity 사용하기

ResponseEntity is meant to represent the entire HTTP response. You can control anything that goes into it: status code, headers, and body.
@ResponseBody is a marker for the HTTP response body and @ResponseStatus declares the status code of the HTTP response.
@ResponseStatus isn't very flexible. It marks the entire method so you have to be sure that your handler method will always behave the same way. And you still can't set the headers. You'd need the HttpServletResponse or a HttpHeaders parameter.
Basically, ResponseEntity lets you do more.

출처 : https://stackoverflow.com/questions/26549379/when-use-responseentityt-and-restcontroller-for-spring-restful-applications

 

When use ResponseEntity and @RestController for Spring RESTful applications

I am working with Spring Framework 4.0.7, together with MVC and Rest I can work in peace with: @Controller ResponseEntity For example: @Controller @RequestMapping("/person") @Profile("

stackoverflow.com


예제

<MemberRestFulController.java>

package com.bitcamp.mm.member.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.bitcamp.mm.member.domain.MemberInfo;
import com.bitcamp.mm.member.service.MemberDeleteService;
import com.bitcamp.mm.member.service.MemberListService;

@CrossOrigin
@RestController // @Responsebody를 생략한다
@RequestMapping("/rest/members")
public class MemberRestFulController {
	
	@Autowired
	private MemberListService listService;
	
	@Autowired
	private MemberDeleteService deleteService;
	
	@GetMapping() // == @RequestMapping(method=RequestMethod.GET)
	// @Responsebody
	// public List<MemberInfo> getAllList(){
	public ResponseEntity<List<MemberInfo>> getAllList(){
		
		List<MemberInfo> list = listService.getAllList();
		
		// ResponseEntity : 4.2버전 이상, @Responsebody대신 쓰는 것, list객체가 JSON타입으로 반환됨 (body, 상태값 설정)
		ResponseEntity<List<MemberInfo>> entity = new ResponseEntity<List<MemberInfo>>(list, HttpStatus.OK);
		// HTTPStatus.NOT_FOUND => 404
		// HTTPStatus.OK => 200
		// HTTPStatus.INTERNAL_SERVER_ERROR => 500
		
		return entity;
	}
	
	@CrossOrigin
	@DeleteMapping("/{id}") // pathVariable -> /rest/members/12 (여기서 '12'를 변수로 받아서 처리해줌)
	public ResponseEntity<String> deleteMember(
			@PathVariable("id") int idx
			) {
		
		//int cnt = deleteService.memberDelete(idx);
		
		return new ResponseEntity<String>(deleteService.memberDelete(idx)>0?"SUCCESS":"FAIL",HttpStatus.OK) ;
	}
}

<rest-client.html>

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <style>
        div.card {
            float: left;
            margin: 2px;
            width: 33%;
            border: 3px solid;
        }

        div#memberlist {
            overflow: hidden;
        }

    </style>
</head>

<body>
    <h1>회원리스트</h1>
    <hr>
    <div id="memberlist">

    </div>

    <script>
        $(document).ready(function() {

            list();

        });

        function del(idx) {

            if (confirm('삭제하시겠습니까?')) {
                $.ajax({
                    url: **'http://localhost:9090/mm/rest/members/' + idx,**
                    type: 'DELETE',
                    success: function(data) {
                        //alert(JSON.stringify(data));
                        if (data == 'SUCCESS') {
                            alert('삭제되었습니다');
                            list();
                        }
                    }
                });
            }
        }

        function list() {
            $.ajax({
                **url: 'http://localhost:9090/mm/rest/members',**
                type: 'GET',
                success: function(data) {
                    //alert(JSON.stringify(data));

                    var html = '';
                    for (var i = 0; i < data.length; i++) {
                        html += '<div class="card">\n';
                        html += 'idx : ' + data[i].idx + '<br>\n';
                        html += 'uId : ' + data[i].uId + '<br>\n';
                        html += 'uName : ' + data[i].uName + '<br>\n';
                        html += 'uPhoto : ' + data[i].uPhoto + '\n';
                        html += '<button onclick="del(' + data[i].idx + ')">삭제하기</button><br>\n';
                        html += '</div>\n';
                    }

                    $('#memberlist').html(html);

                }
            });
        }

    </script>
</body>

</html>

ResponseEntity + 일반 파라미터로 전송

<MemberRestFulController.java>

// JSON 대신 일반 파라미터 형식으로 보낼때 (regRequest)
	@CrossOrigin
	@PostMapping // == @RequestMapping(method=RequestMethod.POST)
	public ResponseEntity<String> regMember(
			RequestMemberRegist regRequest,
			HttpServletRequest request
			) {
		
		int cnt = regService.memberInsert(request, regRequest);
		
		return new ResponseEntity<String>(cnt>0?"SUCCESS":"FAIL",HttpStatus.OK);
	}

<rest-reg.html>

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <style>
        div.card {
            float: left;
            margin: 2px;
            width: 33%;
            border: 3px solid;
        }

        div#memberlist {
            overflow: hidden;
        }
    </style>
</head>

<body>
    <h1>회원가입</h1>
    <hr>
    <form id="form">
        아이디 <input type="text" name="uId" id="uId"><br>
        비밀번호 <input type="password" name="uPw" id="uPw"><br>
        이름 <input type="text" name="uName" id="uName"><br>
        <input type="submit" value="가입">
    </form>

    <script>
        $(document).ready(function() {

            /*var list = {
                uId: 'idididid',
                uPw: 'passsssss',
                uName: '홍길동'
            };*/

            $('#form').submit(function() {

                /*$.ajax({
                    url: 'http://localhost:9090/mm/rest-api/members',
                    type: 'POST',
                    data: JSON.stringify({
                        uId: $('#uId').val(),
                        uPw: $('#uPw').val(),
                        uName: $('#uName').val()
                    }),
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    success: function(data) {
                        alert(data);
                    }
                });*/
                $.ajax({
                    url: 'http://localhost:9090/mm/rest/members',
                    type: 'POST',
                    data: { // uId=abc&uPw=1234&uName=cool 파라미터 형식으로 전달 
														// -> regRequest커맨드 형식으로 전달하기 (JSON이 아니라)
                        uId: $('#uId').val(),
                        uPw: $('#uPw').val(),
                        uName: $('#uName').val()
                    },
	--->	다른 방식으로 처리  data: $('#form').serialize(),
//                    uId: $('#uId').val(),
//                    uPw: $('#uPw').val(),
//                    uName: $('#uName').val() 형식으로 받을 수 있음!! 
                    success: function(data) {
                        alert(data);
                    }
                });
                return false;
            });

        });
    </script>
</body></html>

RestTemplate

1. <RestClientController.java> → CrossOrigin 추가해주기

package com.bitcamp.rc;

import java.util.Arrays;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

@Controller
public class RestfulClientController {
	
	@CrossOrigin
	@RequestMapping("/list")
	@ResponseBody
	public List<MemberInfo> getAllList() {
		
		RestTemplate restTemplate = new RestTemplate();
		
		// get 요청을 보내고 java object로 매핑받아서 반환받음
		MemberInfo[] members = restTemplate.getForObject("http://localhost:9090/mm/rest/members", MemberInfo[].class);
		
		List<MemberInfo> list = Arrays.asList(members);
		
		for(MemberInfo m : list) {
			System.out.println(m);
		}
		
		return list; // view페이지가 아니라 list객체로 리턴받기
	}
	
	@RequestMapping("/member/{idx}")
	public String getMember(
			@PathVariable("idx") int idx
			) {
		
		RestTemplate restTemplate = new RestTemplate();
		MemberInfo info = restTemplate.getForObject("http://localhost:9090/mm/rest/members/{id}", MemberInfo.class, idx);
		
		System.out.println(info);
		
		return null;
	}
	
}

 

2. <MemberRestfulController.java> → CrossOrigin빼주기 ⇒ 회원리스트 나오지 않음

3. <rest-client.html> → url를 'RestClientController'의 url로 바꿔줌

            $.ajax({
                url: 'http://localhost:9090/rc/list',
                type: 'GET',
                success: function(data) {
                    //alert(JSON.stringify(data));

                    var html = '';
                    for (var i = 0; i < data.length; i++) {
                        html += '<div class="card">\n';
                        html += 'idx : ' + data[i].idx + '<br>\n';
                        html += 'uId : ' + data[i].uId + '<br>\n';
                        html += 'uName : ' + data[i].uName + '<br>\n';
                        html += 'uPhoto : ' + data[i].uPhoto + '<br>\n';
                        html += '<button onclick="del(' + data[i].idx + ')">삭제하기</button> ';
                        html += '<button onclick="edmit(' + data[i].idx + ')">수정하기</button><br>\n';
                        html += '</div>\n';
                    }

                    $('#memberlist').html(html);

                }
            });
        }

4. ⇒ 다시 정상적으로 list뽑아낼 수 있음!!! (모든 client에 배포되는 것을 방지함)


RestTemplate 의 동작원리

org.springframework.http.client 패키지에 있다. HttpClient는 HTTP를 사용하여 통신하는 범용 라이브러리이고, RestTemplate은 HttpClient 를 추상화(HttpEntity의 json, xml 등)해서 제공해준다. 따라서 내부 통신(HTTP 커넥션)에 있어서는 Apache HttpComponents 를 사용한다. 만약 RestTemplate 가 없었다면, 직접 json, xml 라이브러리를 사용해서 변환해야 했을 것이다.

  1. 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
  2. RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
  3. RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
  4. ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
  5. RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
  6. ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
  7. RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
  8. 어플리케이션에 반환된다.

출처 : https://sjh836.tistory.com/141

 

RestTemplate (정의, 특징, URLConnection, HttpClient, 동작원리, 사용법, connection pool 적용)

참조문서 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html 1. RestTemplate이란? spring 3.0 부터 지원한다. 스프링에서 제공하는 http..

sjh836.tistory.com


스프링 프레임워크에서는 REST 서비스의 Endpoint를 호출할 수 있도록 크게 2가지 방식인 동기, 비동기 REST Client을 제공합니다. 이번 포스팅에서는 동기방식인 RestTemplate에 대해서 알아보겠습니다.

  • RestTemplate
    • Spring 3부터 지원 되었고 REST API 호출이후 응답을 받을 때까지 기다리는 동기방식이다
  • AsyncRestTemplate
    • Spring 4에 추가된 비동기 RestTemplate이다
    • Spring 5.0에서는 deprecated 되었다
  • WebClient
    • Spring 5에 추가된 논블럭, 리엑티브 웹 클리이언트로 동기, 비동기 방식을 지원한다

RestTemplate은 스프링에서 제공하는 다른 여러 *Template 클래스 (ex. JdbcTemplate, RedisTemplate)와 동일한 원칙에 따라 설계되어 단순한 방식의 호출로 복잡한 작업을 쉽게 하도록 제공합니다. RestTemplate 클래스는 REST 서비스를 호출하도록 설계되어 HTTP 프로토콜의 메서드 (ex. GET, POST, DELETE, PUT)에 맞게 여러 메서드를 제공합니다.

출처 : https://advenoh.tistory.com/46

 

스프링 RestTemplate

Gatsby로 블로그 마이그레이션을 하여 이 링크를 클릭하면 해당 포스팅으로 갑니다. 감사합니다. http://blog.advenoh.pe.kr 1. 들어가며 스프링 프레임워크에서는 REST 서비스의 Endpoint를 호출할 수 있도��

advenoh.tistory.com

300x250