Spring

[Spring] REST API

로아다 2023. 7. 11. 10:56
728x90
반응형
REST

 - HTTP URI 해당 자원을 식별하고 HTTP method로 해당 자원에 대한 CRUD를 구분하여 자원만 리턴하는 방식

 - HTML 페이지가 아닌 자원만 응답하기 때문에 웹 브라우저가 아닌 프로그램에서도 서버를 활용할 수 있다는 장점이 있다.

 - Create, Insert (POST method) POST:/employee - 사원을 추가한다.

 - Read, Select (GET method) GET:/employee/105 - 105 사원을 조회한다.

 - Update (PUT method) PUT:/employee/183 - 183 사원을 수정한다.

 - Delete (DELETE method) DELETE:/employee/170 - 170 사원을 삭제한다.

 

Spring REST

 - @RestController : 해당 클래스가 RestController임을 표시

 - @ResponseBody : 해당 메서드가 뷰 페이지 대신 데이터를 응답한다는 것을 표시

 - @RequestBody : 요청에 실려온 데이터를 바인딩해주는 어노테이션

 - @PathVariable : 요청 URI의 일부분을 변수의 값으로 활용할 수 있다. (일반 컨트롤러에서도 사용 가능)

 

@RestController

 - 일반 컨트롤러와 다르게 다음 뷰를 가리키는 대신 데이터를 응답한다.

 - 컨트롤러의 내부 메서드의 리턴 타입은 뷰를 찾아가는 방식이 아니라 사용자에게 응답할 데이터의 타입을 의미한다.

 - 주로 JSON 또는 XML 형식으로 응답하게 된다.

 

 jackson-databind + jackson-dataformat-xml
<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId>

    <version>2.15.2</version>

</dependency>

<dependency>

    <groupId>com.fasterxml.jackson.dataformat</groupId>

    <artifactId>jackson-dataformat-xml</artifactId>

    <version>2.15.2</version>

</dependency>

 

 - @RestController에서 자바빈 객체(dto)를 리턴하면 알아서 JSON(또는 XML) 형식으로 변환해 응답해주는 라이브러리

 

예시)

package com.ezen.springrest.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.extern.log4j.Log4j;

@RequestMapping("/restful") // 공통되는 주소는 class 쪽으로 뺄 수 있다.
@Log4j
@RestController
public class RestSampleController {
        // @RestController를 추가한 컨트롤러는
        // 내부 메서드의 리턴 타입의 의미가 @Controller와 달라진다.
        
        @GetMapping(value = "/value1", produces = "text/plain; charset=UTF-8")
        public String value1() {
                log.info("hello!");
                return "<h1>Hello, world! 한글도 잘 갑니다</h1>";
        }
        
        @GetMapping(value = "/value2", produces = "text/html; charset=UTF-8")
        public String value2() {
                log.info("hello!");
                return "<h1>Hello, world! 한글도 잘 갑니다</h1>";
        }
}

value1의 결과
value2의 결과

 

JSON으로 데이터 응답하기(상세 [Spring] JSON 참고)
package com.ezen.springrest.controller;

import org.json.simple.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dto.Employee;
import lombok.extern.log4j.Log4j;

@RequestMapping("/restful") // 공통되는 주소는 class 쪽으로 뺄 수 있다.
@Log4j
@RestController
public class RestSampleController {
        
        @GetMapping(value = "/value3", produces = "application/json; charset=UTF-8")
        public String value3() {
                // DB에서 꺼낸 데이터라고 가정
                Employee emp = new Employee();
                
                emp.setFirst_name("steven");
                emp.setLast_name("king");
                emp.setSalary(24000);
                
                JSONObject obj = new JSONObject();
                
                obj.put("first_name", emp.getFirst_name());
                obj.put("last_name", emp.getLast_name());
                obj.put("salary", emp.getSalary());
                
                return obj.toJSONString();
        }
}

value3 결과

 

Jackson 이용해서 JSON / XML 응답하기
package com.ezen.springrest.controller;

import org.json.simple.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dto.Employee;
import lombok.extern.log4j.Log4j;

@RequestMapping("/restful") // 공통되는 주소는 class 쪽으로 뺄 수 있다.
@Log4j
@RestController
public class RestSampleController {
        
        @GetMapping(value = "/employee/json", produces = MediaType.APPLICATION_JSON_VALUE)
        public Employee emp1() {
                Employee e = new Employee();
                
                e.setFirst_name("철수");
                e.setLast_name("김");
                e.setSalary(5000);
                
                return e;
        }
        
        @GetMapping(value = "/employee/xml", produces = MediaType.APPLICATION_XML_VALUE)
        public Employee emp2() {
                Employee e = new Employee();
                
                e.setFirst_name("철수");
                e.setLast_name("김");
                e.setSalary(5000);
                
                return e;
        }
        
}

emp1 결과
emp2 결과

 

ResponseEntity 사용법
package com.ezen.springrest.controller;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dto.Employee;
import lombok.extern.log4j.Log4j;

@RequestMapping("/restful") // 공통되는 주소는 class 쪽으로 뺄 수 있다.
@Log4j
@RestController
public class RestSampleController {
	
	@GetMapping("/resp1")
	public ResponseEntity<String> resp1() {
		// ResponseEntity.ok() : 상태 코드 200인 응답 인스턴스를 생성한다. (마저 만들어야 함)
		ResponseEntity<String> myResponse = ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body("<h1>My Response</h1>");
		
		// ResponseEntity.ok(T body) : 상태 코드 200의 응답 인스턴스를 반환한다.
//              ResponseEntity<String> myResponse = ResponseEntity.ok("<h1>data~</h1>");
	
	return myResponse;
	}

	@GetMapping("/resp2")
	public ResponseEntity<String> resp2() {
		ResponseEntity<String> myResponse = ResponseEntity.status(HttpStatus.NOT_FOUND)
			.contentType(MediaType.parseMediaType("text/plain; charset=UTF-8"))
			.body("<h3>한글 잘 갈듯</h3>");
		
		return myResponse;
	}

	@GetMapping("/resp3")
	public ResponseEntity<String> resp3() throws ParseException {
		ResponseEntity<String> myResponse = ResponseEntity.status(HttpStatus.OK)
			.contentType(MediaType.APPLICATION_JSON)
			.body(new JSONParser().parse("{\"name\":\"박민수\", \"age\":22}").toString());
		
		return myResponse;
	}
}

 

728x90
반응형