Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- GIT
- 스프링 시큐리티
- 목록처리
- /etc/network/interfaces
- 구멍가게코딩단
- 자바편
- 자료구조와함께배우는알고리즘입문
- 친절한SQL튜닝
- 처음 만나는 AI 수학 with Python
- 코드로배우는스프링웹프로젝트
- ㅒ
- network configuration
- 알파회계
- d
- Kernighan의 C언어 프로그래밍
- 선형대수
- baeldung
- 자료구조와 함께 배우는 알고리즘 입문
- 데비안
- 리눅스
- 처음 만나는 AI수학 with Python
- iterator
- 페이징
- 티스토리 쿠키 삭제
- 서버설정
- resttemplate
- 네트워크 설정
- 스프링부트핵심가이드
- 이터레이터
- 코드로배우는스프링부트웹프로젝트
Archives
- Today
- Total
bright jazz music
blog02: POST로 데이터 전송(x-www-form-urlencoded, Json) 본문
Projects/blog
blog02: POST로 데이터 전송(x-www-form-urlencoded, Json)
bright jazz music 2022. 12. 12. 09:50//http method
//GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, TRACE, CONNECT 총 9개
데이터를 보내는 테스트를 해보자.
MockMvc는 기본적으로 contentType을 application/json 형식으로 보낸다.
contentType은 http request 메시지의 바디에 들어가는 데이터 형식을 헤더에 명시해주는 항목이다.
즉, 보내는 자원의 형식을 명시하기 위해 헤더에 실리는 정보 이다. 이 값은 표준 mime-type중의 하나이다
application/x-www-form-urlencoded
그러나 여기서는 우선 과거의 방식인 application/x-www-form-urlencoded로 보내보자.
//PostControllerTest.java
@WebMvcTest
class PostControllerTest {
@Autowired
private MockMvc mockMvc; ////Could not autowire. No beans of 'MockMvc' type found.
@Test
@DisplayName("/posts 요청시 hello world를 출력한다")
void test() throws Exception {
//expected
//기본적으로 Content-Type을 application/json으로 보냄. 예전에는 application/x-www-form-urlencoded를 썼다.
mockMvc.perform(post("/posts")
.contentType(MediaType.APPLICATION_FORM_URLENCODED) //application/x-www-form-urlencoded 사용하기
.param("title", "글 제목입니다.") //map 형태로 헤더에 넣어서 보낸다
.param("content", "글 내용입니다") // 그러나 key:value 방식은 도메인 데이터를 명확히 표현하는 데 한계가 있다. 예를 들어 뎁스가 하나 더 들어간다고 생각해 보자.
)
.andExpect(status().isOk()) //http response 가 200인지
.andExpect(content().string("hello world")) // 내용이 hello world인지
.andDo(print()); //요청에 대한 전반적인 요약을 출력해준다.
}
}
VO역할을 할 클래스를 생성한다.
//PostCreate.java
package com.endofma.blog.request;
public class PostCreate {
public String title;
public String content;
public void setTitle(String title) {
this.title = title;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "PostCreate{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
받는 쪽은 이렇게 받아보자.
//PostController.java
@Slf4j
@RestController
public class PostController {
@PostMapping("/posts")
// public String post(@RequestParam String title, @RequestParam String content){ //각각 받기
// public String post(@RequestParam Map<String, String> params){ //map으로 받기
public String post(@ModelAttribute PostCreate params) { //데이터 형태에 맞는 클래스, 즉 VO로 받기
log.info("params={}", params.toString());
return "hello world";
}
}
결과 출력
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.6)
2022-12-12 10:26:09.057 INFO 15068 --- [ Test worker] c.e.blog.controller.PostControllerTest : Starting PostControllerTest using Java 11.0.12 on DESKTOP-Q7HBM41 with PID 15068 (started by user in D:\personal\work\blog)
2022-12-12 10:26:09.059 INFO 15068 --- [ Test worker] c.e.blog.controller.PostControllerTest : No active profile set, falling back to 1 default profile: "default"
2022-12-12 10:26:10.667 INFO 15068 --- [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2022-12-12 10:26:10.667 INFO 15068 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2022-12-12 10:26:10.670 INFO 15068 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 3 ms
2022-12-12 10:26:10.721 INFO 15068 --- [ Test worker] c.e.blog.controller.PostControllerTest : Started PostControllerTest in 2.273 seconds (JVM running for 4.824)
2022-12-12 10:26:11.360 INFO 15068 --- [ Test worker] c.e.blog.controller.PostController : params=PostCreate{title='글 제목입니다.', content='글 내용입니다'}
MockHttpServletRequest:
HTTP Method = POST
Request URI = /posts
Parameters = {title=[글 제목입니다.], content=[글 내용입니다]}
Headers = [Content-Type:"application/x-www-form-urlencoded;charset=UTF-8"]
Body = null
Session Attrs = {}
Handler:
Type = com.endofma.blog.controller.PostController
Method = com.endofma.blog.controller.PostController#post(PostCreate)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"text/plain;charset=UTF-8", Content-Length:"11"]
Content type = text/plain;charset=UTF-8
Body = hello world
Forwarded URL = null
Redirected URL = null
Cookies = []
BUILD SUCCESSFUL in 10s
4 actionable tasks: 3 executed, 1 up-to-date
AM 10:26:11: Execution finished ':test --tests "com.endofma.blog.controller.PostControllerTest.test"'.
그러나 application/x-www-form-urlencoded 형식은 데이터를 키 맵 형태로 나열해야 하기 때문에 온전히 데이터를 표현하기 어렵다. 구분하기도 어렵다. json 형식의 경우 아래와 같이 데이터 표현이 가능하다.
application/json으로 보내기
//PostControllerTest.java
@WebMvcTest
class PostControllerTest {
@Autowired
private MockMvc mockMvc; ////Could not autowire. No beans of 'MockMvc' type found.
@Test
@DisplayName("/posts 요청시 hello world를 출력한다")
void test() throws Exception {
//expected
//기본적으로 Content-Type을 application/json으로 보냄. 예전에는 application/x-www-form-urlencoded를 썼다.
mockMvc.perform(post("/posts")
// .contentType(MediaType.APPLICATION_JSON) //미디어 타입을 변경해 주었다.
.content("{\"title\": \"제목입니다.\", \"content\": \"내용입니다.\"}") //json 형태로 값 넣어주기
)
.andExpect(status().isOk()) //http response 가 200인지
.andExpect(content().string("hello world")) // 내용이 hello world인지
.andDo(print()); //요청에 대한 전반적인 요약을 출력해준다.
}
}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.6)
2022-12-12 11:16:52.921 INFO 19892 --- [ Test worker] c.e.blog.controller.PostControllerTest : Starting PostControllerTest using Java 11.0.12 on DESKTOP-Q7HBM41 with PID 19892 (started by user in D:\personal\work\blog)
2022-12-12 11:16:52.925 INFO 19892 --- [ Test worker] c.e.blog.controller.PostControllerTest : No active profile set, falling back to 1 default profile: "default"
2022-12-12 11:16:54.642 INFO 19892 --- [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2022-12-12 11:16:54.642 INFO 19892 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2022-12-12 11:16:54.645 INFO 19892 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 3 ms
2022-12-12 11:16:54.689 INFO 19892 --- [ Test worker] c.e.blog.controller.PostControllerTest : Started PostControllerTest in 2.352 seconds (JVM running for 4.807)
2022-12-12 11:16:55.279 INFO 19892 --- [ Test worker] c.e.blog.controller.PostController : params=PostCreate{title='null', content='null'}
MockHttpServletRequest:
HTTP Method = POST
Request URI = /posts
Parameters = {}
Headers = [Content-Length:"60"]
Body = {"title": "제목입니다.", "content": "내용입니다."}
Session Attrs = {}
Handler:
Type = com.endofma.blog.controller.PostController
Method = com.endofma.blog.controller.PostController#post(PostCreate)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"text/plain;charset=UTF-8", Content-Length:"11"]
Content type = text/plain;charset=UTF-8
Body = hello world
Forwarded URL = null
Redirected URL = null
Cookies = []
BUILD SUCCESSFUL in 8s
4 actionable tasks: 3 executed, 1 up-to-date
AM 11:16:55: Execution finished ':test --tests "com.endofma.blog.controller.PostControllerTest.test"'.
출력 내용에서 요청이 전달되는 것을 확인할 수 있다.
MockHttpServletRequest:
HTTP Method = POST
Request URI = /posts
Parameters = {}
Headers = [Content-Length:"60"]
Body = {"title": "제목입니다.", "content": "내용입니다."}
Session Attrs = {}
문제는 아래와 같이 VO에 값이 담아지지 않는다는 것이다.
2022-12-12 11:16:55.279 INFO 19892 --- [ Test worker] c.e.blog.controller.PostController : params=PostCreate{title='null', content='null'}
이는 우리가 아래와 같이 @ModelAttribute로 데이터를 받았기 때문이다.
public String post(@ModelAttribute PostCreate params) {...}
@RequestBody로 받아야 한다.
ㅇ
//PostController.java
@Slf4j
@RestController
public class PostController {
@PostMapping("/posts")
public String post(@RequestBody PostCreate params) { //데이터 형태에 맞는 클래스, 즉 VO로 받기
log.info("params={}", params.toString());
return "hello world";
}
}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.6)
2022-12-12 11:30:33.394 INFO 5520 --- [ Test worker] c.e.blog.controller.PostControllerTest : Starting PostControllerTest using Java 11.0.12 on DESKTOP-Q7HBM41 with PID 5520 (started by user in D:\personal\work\blog)
2022-12-12 11:30:33.398 INFO 5520 --- [ Test worker] c.e.blog.controller.PostControllerTest : No active profile set, falling back to 1 default profile: "default"
2022-12-12 11:30:35.232 INFO 5520 --- [ Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2022-12-12 11:30:35.233 INFO 5520 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2022-12-12 11:30:35.235 INFO 5520 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 2 ms
2022-12-12 11:30:35.278 INFO 5520 --- [ Test worker] c.e.blog.controller.PostControllerTest : Started PostControllerTest in 2.53 seconds (JVM running for 5.149)
2022-12-12 11:30:35.953 INFO 5520 --- [ Test worker] c.e.blog.controller.PostController : params=PostCreate{title='제목입니다.', content='내용입니다.'}
MockHttpServletRequest:
HTTP Method = POST
Request URI = /posts
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"60"]
Body = {"title": "제목입니다.", "content": "내용입니다."}
Session Attrs = {}
Handler:
Type = com.endofma.blog.controller.PostController
Method = com.endofma.blog.controller.PostController#post(PostCreate)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"text/plain;charset=UTF-8", Content-Length:"11"]
Content type = text/plain;charset=UTF-8
Body = hello world
Forwarded URL = null
Redirected URL = null
Cookies = []
BUILD SUCCESSFUL in 8s
4 actionable tasks: 2 executed, 2 up-to-date
AM 11:30:36: Execution finished ':test --tests "com.endofma.blog.controller.PostControllerTest.test"'.
아래와 같이 PostCreate 객체에 바인딩 된 값이 출력되는 것을 확인할 수 있다.
2022-12-12 11:30:35.953 INFO 5520 --- [ Test worker] c.e.blog.controller.PostController : params=PostCreate{title='제목입니다.', content='내용입니다.'}
'Projects > blog' 카테고리의 다른 글
blog04: 작성글 저장1 - 게시글 저장 구현 (0) | 2022.12.28 |
---|---|
blog03: 데이터 검증3 (ExceptionController) (0) | 2022.12.27 |
blog03: 데이터 검증2 (ExceptionController, @ControllerAdvice) (0) | 2022.12.13 |
blog03: 데이터 검증1 (@NotBlank, @Valid, BindingResult) (0) | 2022.12.12 |
blog01 : 프로젝트 생성/기본 RestController 생성/테스트 수행 (0) | 2022.12.10 |
Comments