스프링 프레임워크

REST 그리고 Ajax

tttck88 2019. 5. 31. 20:43

REST

REST는 하나의 URI는 하나의 고유한 리소스를 대표하도록 설계된다는 개념이다.

즉 REST방식은 특정한 URI는 반드시 그에 상응하는 데이터 자체라는 것을 의미하는 방식이다.

 

@RestController

기존의특정한 JSP와 같은 뷰를 만들어 내는 것이 목적이 아닌 REST 방식의 데이터 처리를 위해서 사용하는 애노테이션이다. 즉 JSP와 같은 뷰를 만들어 내지 않는 대신에 데이터 자체를 반환하는데, 이떄 주로 사용하는 것은 단순 문자열과 JSON, XML 등으로 나누어 볼 수 있다. 기존에는 해당 메소드나 리턴 타입에 @ResponseBody 어노테이션을 추가하는 형태로 작성하였는데 컨트롤러 자체의 용도를 지정하는점에서 변화가 있다고 할 수 있다.

 

단순문자열의 경우

문자열 데이터는 기본적으로 브라우저에서 'text/html'타입으로 처리된다.

@RestController
@RequestMapping("/sample")
public class SampleContorller {
	
	@RequestMapping("/hello")
	public String sayHello() {
		return "Hello World";
	}
}

@RestController 어노테이션이 사용된 클래스의 모든 메소드는 @ResponseBody가 없어도 동일하게 동작한다(생략되었다고 생각해도 무방하다.)

sayHello()는 문자열을 결과로 반환하게 되어 있다. 특이한 점은 결과로 반환하는 문자열이 JSP의 경로가 아닌 일반 문자열이라는것이다.

 

객체를 JSON으로 반환하는 경우

@RestController의 경우 별도의 처리가 없어도 객체는 자동으로 JSON으로 처리될 수 있다.

	@RequestMapping("/sendVO")
	public SampleVO sendVO() {
		
		SampleVO vo = new SampleVO();
		vo.setFirstName("�浿");
		vo.setLastname("ȫ");
		vo.setMno(123);
		
		return vo;
	}

작성된 sendVO()의 반환 타입을 보면 SampleVO 타입으로 선언된 것이 보인다.

메소드 내부에서는 해당 타입의 객체를 생성하고 이를 반환하다.

결과 메시지를 보면 문자열로 되어 있지만 JSON의 형태로 결과가 만들어진 것을 볼 수 있다.

개발자 도구에서 응답헤더의 내용을 확인해보면 appllication/json으로 되어 있는 것을 확인할 수 있다.

 

Ajax

Ajax 사용에 있어서 큰 특징은 1) 브라우저의 화면 전환이 없기 때문에 사용자 경험 측면에서 좋다는 점과 2) 서버에서 화면에 필요한 모든 데이터를 만드는 대신 서버는 필요한 데이터만 전달하기 때문에, 개발의 무게 주잇ㅁ이 브라우저 쪽으로 많이 배분된다는 점이 있다.

 

REST와 Ajax

REST 방식이 데이터를 호출하고, 사용하는 방식을 의미한다면 Ajax는 실제로 그를 이요하는 수단에 가깝다고 할 수 있다.

 

REST 방식의 처리에서 사용하는 어노테이션

@PathVariable - URI 경로에서 원하는 데이터를 추출하는 용도로 사용

@RequestBody - 전송된 JSON 데이터를 객체로 변환해 주는 어토이션으로 @ModelAttribute와 유사한 역할을 하지만 JSON에서 사용된다는 점이 차이

	@RequestMapping(value = "", method = RequestMethod.POST)
	public ResponseEntity<String> register(@RequestBody ReplyVO vo) {
		
		ResponseEntity<String> entity = null;
		try {
			service.addReply(vo);
			entity = new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
			
		}
		return entity;
	}
	
	@RequestMapping(value = "/all/{b_id}", method = RequestMethod.GET)
	public ResponseEntity<List<ReplyVO>> list(@PathVariable("b_id") Integer b_id) {
		
		ResponseEntity<List<ReplyVO>> entity = null;
		try {
			entity = new ResponseEntity<>(service.listReply(b_id), HttpStatus.OK);
		} catch (Exception e) {
			e.printStackTrace();
			entity = new ResponseEntity<>(HttpStatus.BAD_REQUEST);
			
		}
		return entity;
	}

@RequestMapping()을 보면 URI 내의 경로 {b_id}를 활용한다. {bno}는 메소드의 파라미터에서 @PathVariable("b_id")로 활용된다.

 

HiddenMethod의 활용

브라우저에 따라서 PUT,PATCH,DELETE 방식을 지원하지 않는 경우가 발생할 수 있기에 그러한 상황에서의 대해서도 고려해야 한다. 대부분의 해결책은 부라우저에서 POST 방식으로 전송하고, 추가적인 정보를 이용해서 PUT,PATCH,DELETE와 같은 정보를 같이 전송하는 것이다. 이를 'Overloaded POST'라고 한다.

		$.ajax({
			type : 'delete',
			url : '/replies/' + r_id,
			headers : {
				"Content-Type" : "application/json",
				"X-HTTP-Method-Override" : "DELETE"
			},
			dataType : 'text',
			success : function(result) {
				console.log("result: " + result);
				if (result == 'SUCCESS') {
					alert("삭제 되었습니다.");
					$("#modDiv").hide("slow");
					getAllList();
				}
			}
		});

코드의 내용 중 "X-HTTP-Method-Override" 정보를 이용하는 것을 볼 수 있다.

 

<form> 태그를 이용해서 데이터를 전송하는 경우에는 POST 방식으로 전송하되, '_method'라는 추가적인 정보를 이용한다. 스프링은 이를 위해서 HiddenHttpMethodFilter라는 것을 제공한다. HiddenHttpMethodFilter는 <form> 태그 내에서 <input type="hidden" name="_method" value="PUT">과 같은 형태로 사용해서 GET/POST 방식만을 지원하는 브라우저에서 REST 방식을 사용할 수 있도록 설정할때 쓰인다.

	<filter>
		<filter-name>hiddenHttpMethodFilter</filter-name>
		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>hiddenHttpMethodFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>