๐Ÿ“—Spring MVC Study [ HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ ]

Caruhยท2025๋…„ 3์›” 24์ผ

Spring MVC

๋ชฉ๋ก ๋ณด๊ธฐ
16/17
post-thumbnail

HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ

  • ๋ทฐ ํ…œํ”Œ๋ฆฟ์œผ๋กœ HTML์„ ์ƒ์„ฑํ•ด์„œ ์‘๋‹ตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, HTTP API์ฒ˜๋Ÿผ JSON ๋ฐ์ดํ„ฐ๋ฅผ HTTP ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์—์„œ ์ง์ ‘ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒฝ์šฐ HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌ.

@ResponseBody๋ฅผ ์‚ฌ์šฉ

  • HTTP์˜ BODY์— ๋ฌธ์ž ๋‚ด์šฉ์„ ์ง์ ‘ ๋ฐ˜ํ™˜
  • viewResolver ๋Œ€์‹ ์— HttpMessageConverter๊ฐ€ ๋™์ž‘
  • ๊ธฐ๋ณธ ๋ฌธ์ž์ฒ˜๋ฆฌ : StringHttpMessageConverter
  • ๊ธฐ๋ณธ ๊ฐ์ฒด์ฒ˜๋ฆฌ : MappingJackson2HttpMessageConverter
  • byte ์ฒ˜๋ฆฌ ๋“ฑ๋“ฑ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ HttpMessageConverter๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์Œ

์ฐธ๊ณ 

  • ์‘๋‹ต์˜ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ์˜ HTTP Aceept ํ—ค๋”์™€ ์„œ๋ฒ„์˜ ์ปจํŠธ๋กค๋Ÿฌ ๋ฐ˜ํ™˜ ํƒ€์ž… ์ •๋ณด ๋‘˜์„ ์กฐํ•ฉํ•ด์„œ HttpMessageConverter๊ฐ€ ์„ ํƒ๋œ๋‹ค.

์Šคํ”„๋ง MVC๋Š” ๋‹ค์Œ์˜ ๊ฒฝ์šฐ์—๋Š” HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์ ์šฉํ•œ๋‹ค.

  • HTTP ์š”์ฒญ : @RequestBody, HttpEntity(RequestEntity),
  • HTTP ์‘๋‹ต : @ResponseBody, HttpEntity(ResponseEntity)

HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค

 public interface HttpMessageConverter<T> {
 	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
 	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
 	List<MediaType> getSupportedMediaTypes();
 	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
 	throws IOException, HttpMessageNotReadableException;
 	void write(T t, @Nullable MediaType contentType, HttpOutputMessage 
	outputMessage)
 	throws IOException, HttpMessageNotWritableException;
 }

HTTP ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋Š” HTTP ์š”์ฒญ, HTTP ์‘๋‹ต ๋‘˜ ๋‹ค ์‚ฌ์šฉ๋œ๋‹ค.

  • canRead(), canWrite() : ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ํ•ด๋‹น ํด๋ž˜์Šค, ๋ฏธ๋””์–ด ํƒ€์ž…์„ ์ง€์›ํ•˜๋Š”์ง€ ์ฒดํฌ
  • read(), write() : ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ํ†ตํ•ด์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  ์“ฐ๋Š” ๊ธฐ๋Šฅ

์Šคํ”„๋ง ๋ถ€ํŠธ ๊ธฐ๋ณธ ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ

0ByteArrayHttpMessageConverter
1StringHttpMessageConverter
2MappingJackson2HttpMessageConverter
  • ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” ๋‹ค์–‘ํ•œ ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ, ๋Œ€์ƒ ํด๋ž˜์Šค ํƒ€์ž…๊ณผ ๋ฏธ๋””์–ด ํƒ€์ž… ๋‘˜์„ ์ฒดํฌํ•ด์„œ ์‚ฌ์šฉ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ๋งŒ์•ฝ ๋งŒ์กฑํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋กœ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋„˜์–ด๊ฐ„๋‹ค.

๋ช‡๊ฐ€์ง€ ์ฃผ์š”ํ•œ ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์•Œ์•„๋ณด์ž.

  • ByteArrayHttpMessageConverter: byte[] ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ํด๋ž˜์Šค ํƒ€์ž… : byte[], ๋ฏธ๋””์–ด ํƒ€์ž…: */*,
    • ์š”์ฒญ ์˜ˆ) @RequestBody byte[] data
    • ์‘๋‹ต ์˜ˆ) @ResponseBody return byte[] ์“ฐ๊ธฐ ๋ฏธ๋””์–ดํƒ€์ž… application/octet-stream
  • StringHttpMessageConverter:String๋ฌธ์ž๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ํด๋ž˜์Šค ํƒ€์ž… : String, ๋ฏธ๋””์–ด ํƒ€์ž…: */*
    • ์š”์ฒญ ์˜ˆ) @RequestBody String data
    • ์‘๋‹ต ์˜ˆ) @ResponseBody return "ok"์“ฐ๊ธฐ ๋ฏธ๋””์–ดํƒ€์ž… text/plain
  • MappingJackson2HttpMessageConverter: application/json
    • ํด๋ž˜์Šค ํƒ€์ž… : ๊ฐ์ฒด ๋˜๋Š” HashMap, ๋ฏธ๋””์–ดํƒ€์ž… application/json ๊ด€๋ จ
    • ์š”์ฒญ ์˜ˆ) @RequestBody HelloData data
    • ์‘๋‹ต ์˜ˆ) @ResponseBody return helloData ์“ฐ๊ธฐ ๋ฏธ๋””์–ดํƒ€์ž… application/json๊ด€๋ จ

StringHttpMessageConverter

content-type: application/json

@RequestMapping
void hello(@RequestBody String data) {}

MappingJackson2HttpMessageConverter

content-type: application/json

@RequestMapping
void hello(@RequestBody HelloData data) {}

?

content-type: text/html

@RequestMapping
void hello(@RequestBody HelloData data) {}

HTTP ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ

  • HTTP ์š”์ฒญ์ด ์˜ค๊ณ , ์ปจํŠธ๋กค๋Ÿฌ์—์„œ @RequestBody, HttpEntity ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด canRead()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    • ๋Œ€์ƒ ํด๋ž˜์Šค ํƒ€์ž… ์ง€์›ํ•˜๋Š”๊ฐ€.
      • ์˜ˆ) @RequestBody์˜ ๋Œ€์ƒ ํด๋ž˜์Šค (byte[], String, HelloData)
    • HTTP ์š”์ฒญ์˜ Content-Type ๋ฏธ๋””์–ด ํƒ€์ž…์„ ์ง€์›ํ•˜๋Š”๊ฐ€.
      • ์˜ˆ) text/plain, application/json, */*
  • canRead() ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด read()๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ฐ์ฒด ์ƒ์„ฑํ•˜๊ณ , ๋ฐ˜ํ™˜ํ•œ๋‹ค.

HTTP ์‘๋‹ต ๋ฐ์ดํ„ฐ ์ƒ์„ฑ

  • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ @ResponseBody, HttpEntity๋กœ ๊ฐ’์ด ๋ฐ˜ํ™˜๋œ๋‹ค.
  • ๋ฉ”์‹œ์ง€ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด canWrite()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    • ๋Œ€์ƒ ํด๋ž˜์Šค ํƒ€์ž…์„ ์ง€์›ํ•˜๋Š”๊ฐ€.
      • ์˜ˆ) return์˜ ๋Œ€์ƒ ํด๋ž˜์Šค (byte[], String, HelloData)
    • HTTP ์š”์ฒญ์˜ Accept ๋ฏธ๋””์–ด ํƒ€์ž…์„ ์ง€์›ํ•˜๋Š”๊ฐ€. (๋” ์ •ํ™•ํžˆ๋Š” @RequestMapping์˜ produces)
      • ์˜ˆ) text/plain, application/json, */*
  • canWrite() ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด write()๋ฅผ ํ˜ธ์ถœํ•ด์„œ HTTP ์‘๋‹ต ๋ฉ”์‹œ์ง€ ๋ฐ”๋””์— ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

๐Ÿ“ญ Reference

profile
Backend Developer

0๊ฐœ์˜ ๋Œ“๊ธ€