참고 : https://elfinlas.github.io/2018/02/18/spring-parameter/
이런 형식의 Url 창을 한번쯤은 본적이 있을것이다.
사실 이것이 rest한 방식이라는 것을 그리고 그것을 전세계 웹개발자들과 사용자들이 웹을 사용할때 약속한 방식(아키텍처)라는 것을 안지는 얼마 되지 않았다. 왜냐? 나는 약속한적이 없고 그냥 이렇게 쓰니까 원래 이렇게 쓰는 줄 알았다.
여튼 rest와 restful한 api의 차이점을 알고 싶으면 아래의 참고링크를 걸어두겠다.
참고 : https://velog.io/@sago_mungcci/Rest-RESTful-API%EB%9E%80
@GetMapping("/shcool/grade/{id}")
// @pathVariable로 해당 URL의 id를 받아옴.
public ResponseEntity<BasicResponse> readPostOne(@PathVariable Long id) {
BasicResponse basicResponse = new BasicResponse();
.....
@GetMapping("/shcool/class")
// @pathVariable로 해당 URL의 id를 받아옴.
public ResponseEntity<BasicResponse> readPostOne(@RequestParam("name") int page) {
BasicResponse basicResponse = new BasicResponse();
.....
@PostMapping("/shcool/class")
public ResponseEntity<BasicResponse> readPostOne(@RequestParam String name, int page) {
System.out.println(">>> " + name);
System.out.println(">>> " + page);
return "result";
}
참고 : https://ocblog.tistory.com/49?category=395154
@PostMapping("/shcool/class")
public ResponseEntity<BasicResponse> readPostOne(@RequestBody String name, int page) {
System.out.println(">>> " + name);
System.out.println(">>> " + page);
return "result";
}
//출력 결과
//통신 성공
//>>> name=apple&page=2
- 그러나 리소스의 행위로 클라이언트가 요청하는 것이 아니라 JSON으로 리소스의 행위에 JSON으로 표현하여 요청하면 어떨까?
이런 형태의 Json이 있다고 가정하자.
바로위에 있는 코드에 @RequestBody가 아닌 @RequestParam으로 바꾼다면 다음과 같은 에러가 발생한다.
MissingServletRequestParameterException: Required String parameter 'name' is not present
name 이라는 파라미터가 없다고 한다.
그 이유는 기본적으로 @RequestParam 은 url 상에서 데이터를 찾기 때문이다.
우리가 위에서 <form'> 태그를 이용하여 데이터를 입력하고 제출 버튼을 누르면 입력한 데이터들이 url을 통해서 전달된다.
예를 들면 'http://localhost:8080/grade?name=apple&page=2' 이런 식이다.
반면에 Json형식으로 데이터를 전달할때는, url은 http://localhost:8080/grade 변함이 없고 body에 데이터를 포함하여 전송하기 때문에 @RequestParam 으로는 받을 수 없는 것이다.
@PostMapping("/shcool/class")
public ResponseEntity<BasicResponse> readPostOne(@RequestBody String name, int page) {
System.out.println(">>> " + name);
System.out.println(">>> " + page);
return "result";
}
/출력 결과
//통신 성공
//>>> {"name":"apple","page":"2"}
하지만 여기에는 큰 차이가 있다.
만약 다음과 같이 name과 page 를 필요로 하는 Person 클래스가 있고 getter 가 구현되어 있다면
public class Person {
private String name;
private int page;
public Person() {
}
public Person(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getPage() {
return page;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", page=" + page +
'}';
}
}
@PostMapping("/shcool/class")
public ResponseEntity<BasicResponse> readPostOne(@RequestBody Person person) {
System.out.println(">>> " + name);
System.out.println(">>> " + page);
return "result";
}
/출력 결과
//통신 성공
//>>> {"name":"apple","page":"2"}
신기하게도 Person 객체를 자동으로 생성해 주었다.
@RequestBody 가 아닌 @RequestParam 을 이용한다면 불가능하다. 한번 시도해보자.
출처 : https://dahliachoi.tistory.com/44
요청 파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣어주어야 한다.
보통 @RequestParam을 사용해서 값을 받고, set을 사용해서 값을 넣어주곤 하지만 이 과정을 자동화시켜주는 것이 @ModelAttribute이다.
- @ModelAttribute를 사용하지 않을 때 (model도 같이 사용해보기)
public void item(@RequestParam String name,
@RequestParam int price,
Model model){
Item item = new Item();
item.setName(name);
item.setPrice(price);
model.addAttribute("item", item);
}
- modelAttribute 사용
public void modelAttributeEx(@ModelAttribute Item item, Model model){
model.addAttribute("item", item);
}
이렇게 간결하게 사용 가능하다.
@ModelAttribute가 실행되는 원리를 설명하자면 요청 파라미터의 이름으로 Item 객체의 프로퍼티를 찾는다.
해당 프로퍼티의 setter를 호출해서 파라미터 값을 입력한다.
하지만 저기에서 model.addAttribute도 생략 가능하다. @ModelAttribute를 사용함으로써 model에도 자동적으로 객체가 추가 되기 때문이다.
@ModelAttribute 어노테이션도 생략가능하다.
public void ModelAttributeEx(Item item, Model model){}
출처 : 항해99 스프링 심화 1주차 강의자료