스프링 부트

[SpringBoot] ajax - application/x-www-form-urlencoded 로 요청하기!

h__hj 2022. 8. 13. 20:14

# ajax - application/x-www-form-urlencoded

 jQuery ajax 의 contentType이 (default) application/x-www-form-urlencoded; charset=utf-8 일 때, @RequestParam, @ModelAttribute 로 파라미터 매핑하기.

# 환경

/**
 * tool: STS 4.13.0
 * version: 2.7.3-SNAPSHOT
 * java: 1.8
 * type: MAVEN
 * view: THYMELEAF
 * jQuery: 3.6.0
 */

# page

# html (일부분 발췌)

<h1>통신 테스트 페이지 입니다.</h1>
<h3>GET, POST (application/x-www-form-urlencoded)</h3>
<input type="text" id="requsets" placeholder="Request Test" style="display: inline;"/>
<br>

<input type="button" onclick="test.requsets('get1')" value="GET1" style="display: inline;"/>
<input type="button" onclick="test.requsets('get2')" value="GET2" style="display: inline;"/>
<input type="button" onclick="test.requsets('get3')" value="GET3" style="display: inline;"/>
<br>

<input type="button" onclick="test.requsets('post1')" value="POST1" style="display: inline;"/>
<input type="button" onclick="test.requsets('post2')" value="POST2" style="display: inline;"/>
<input type="button" onclick="test.requsets('post3')" value="POST3" style="display: inline;"/>
<input type="button" onclick="test.requsets('post4')" value="POST4" style="display: inline;"/>
<input type="button" onclick="test.requsets('post5')" value="POST5" style="display: inline;"/>
<input type="button" onclick="test.requsets('post6')" value="POST6" style="display: inline;"/>
<input type="button" onclick="test.requsets('post7')" value="POST7" style="display: inline;"/>
<br>

# function (일부분 발췌)

const test = {
    requsets: function(method) {
        const value = $('#requsets').val();
        const type = (method.startsWith('post')) ? "post" : "get";
        
        const input = {
            param1: value,
            param2: method,
        }
        sendRequest(`/test/send/${method}`, type, input,
            function(result) {
                console.log(result.param1);
                console.log(result.param2);
            } 
        );
    }
}

# jQuery ajax (일부분 발췌)

function sendRequest(url, method, input, cbSuccess) {
    $.ajax({
    // options
        url         : url,
        method      : (method) ? method : "POST",
        data        : input,
        dataType    : "json", 
        beforeSend  : function(jqXHR, settings) {
            // throw '에러';
            // return false;
        }
    // success
    }).done(function(output, textStatus, jqXHR) {
        if(typeof cbSuccess === 'function') {
            cbSuccess(output);
        }
    // error	
    }).fail(function(jqXHR) {
        console.log("ERROR");
    // complete
    }).always(function(output, textStatus, jqXH) {
        console.log("COMPLETE");
    });
}

# @Controller (일부분 발췌)

@Slf4j
@Controller
@RequestMapping("/test/send")
public class TestSendController {

	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * RequestParam 변수 이름과 ajax data prameter의 변수가 같음.
	 * 사용가능
	 */
	@PostMapping("/post1")
	public @ResponseBody Map<String, Object> post1(String param2, @RequestParam String param1) {
		log.debug("[PARAMETER] {}, {}", param1, param2);
		
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", param1);
		response.put("param2", param2);
		
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * RequestParam 의 변수 이름은 다르지만, value값과 ajax data prameter의 변수가 같음.
	 * 사용가능
	 */
	@PostMapping("/post2")
	@ResponseBody
	public Map<String, Object> post2(@RequestParam("param1") String request1, @RequestParam("param2") String request2) {
		log.debug("[PARAMETER] {}, {}", request1, request2);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", request1);
		response.put("param2", request2);
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * ModelAttribute VO를 맵핑할 떄 사용. 해당 VO의 변수값과 ajax data prameter의 변수가 같음.
	 * 사용가능
	 */
	@PostMapping("/post3")
	@ResponseBody
	public Map<String, Object> post3(@ModelAttribute TestSendPVO testSendPVO) {
		log.debug("[PARAMETER] {}", testSendPVO);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", testSendPVO.getParam1());
		response.put("param2", testSendPVO.getParam2());
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * ModelAttribute 없어도 사용가능. 해당 VO의 변수값과 ajax data prameter의 변수가 같음.
	 * 사용가능
	 */
	@PostMapping("/post4")
	@ResponseBody
	public Map<String, Object> post4(TestSendPVO testSendPVO) {
		log.debug("[PARAMETER] {}", testSendPVO);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", testSendPVO.getParam1());
		response.put("param2", testSendPVO.getParam2());
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * RequestParam 을 Map으로 받는다. ajax data prameter의 변수가 맵핑됨.
	 * 사용가능
	 */
	@PostMapping("/post5")
	@ResponseBody
	public Map<String, Object> post5(@RequestParam Map<String, String> input) {
		log.debug("[PARAMETER] {}", input);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", input.get("param1"));
		response.put("param2", input.get("param2"));
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * RequestBody 는 application/x-www-form-urlencoded을 지원하지 않는다.
	 * 사용불가
	 */
	@PostMapping("/post6")
	@ResponseBody
	public Map<String, Object> post6(@RequestBody TestSendPVO testSendPVO) {
		log.debug("[PARAMETER] {}", testSendPVO);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", testSendPVO.getParam1());
		response.put("param2", testSendPVO.getParam2());
		return response;
	}
	/**
	 * ajax contentType: application/x-www-form-urlencoded; charset=utf-8 <br>
	 * 일반 Map이면 아예 파라미터라고 생각 안하는 듯.
	 * 사용불가
	 */
	@PostMapping("/post7")
	@ResponseBody
	public Map<String, Object> post7(Map<String, String> input) {
		log.debug("[PARAMETER] {}", input);
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", input.get("param1"));
		response.put("param2", input.get("param2"));
		return response;
	}
    // 사용가능
	@GetMapping("/get1")
	public @ResponseBody Map<String, Object> get1(@RequestParam String param1, @RequestParam String param2) {
		log.debug("[PARAMETER] {}, {}", param1, param2);
		
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", param1);
		response.put("param2", param2);
		
		return response;
	}
	// 사용가능
	@GetMapping("/get2")
	public @ResponseBody Map<String, Object> get2(@RequestParam Map<String, String> input) {
		log.debug("[PARAMETER] {}", input);
		
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", input.get("param1"));
		response.put("param2", input.get("param2"));
		
		return response;
	}
    // 사용가능
	@GetMapping("/get3")
	public @ResponseBody Map<String, Object> get3(@ModelAttribute TestSendPVO testSendPVO) {
		log.debug("[PARAMETER] {}", testSendPVO);
		
		Map<String, Object> response = new HashMap<String, Object>();
		response.put("param1", testSendPVO.getParam1());
		response.put("param2", testSendPVO.getParam2());
		
		return response;
	}
}

# 내용

 ajax의 contentType이 application/x-www-form-urlencoded; charset=utf-8 일 때

@Controller 의 @GetMapping, @PostMapping 메소드에서 ajax 파라미터 받는 법 정리는 아래와 같다. 

  1. 하나의 파라미터를 받을 경우.
    • @RequestParam 으로 설정한 변수명과 ajax 파라미터의 변수명이 같으면 됨. (=post1, get1)
    • @RequestParam 으로 설정한 value 값과 ajax 파라미터의 변수명가 같으면 됨. (=post2)
      • @RequestParam("변수명") or (value="변수명") or (name="변수명")
    • Annotation 없이 메소드 인자의 변수명과 ajax 파라미터의 변수명이 같으면 됨. (=post1)
  2. 파라미터 전체를 받을 경우.
    • @ReqeustParam 을 Map<String, String> 으로 설정하면 됨. (=post5, get2)
    • @ModelAttribute 로 VO를 설정하고, VO의 변수명과 ajax 파라미터의 변수명이 같으면 됨. (=post3, get3)
    • Annotation 없이 VO로 설정하고, VO의 변수명과 ajax 파라미터의 변수명이 같으면 됨. (=post4)
  3. 파라미터를 받지 못하는 경우.
    • @RequestBody: GET, POST 구분 없이 x-www-form-urlencoded 는 @RequestBody를 지원하지 않음.
    • VO를 @RequestParam 으로 설정할 경우.
    • Annotation 없이 Map 으로 설정할 경우.
    • @RequestParam 의 value값과 변수명 둘 다 다를 경우.

# ajax 요청 방식에 따른 파라미터 맵핑 방법.

https://hjho95.tistory.com/14 ajax settings
https://hjho95.tistory.com/7 application/x-www-form-urlencoded
https://hjho95.tistory.com/8 application/json
https://hjho95.tistory.com/9 form tag
https://hjho95.tistory.com/10 multipart/form-data
https://hjho95.tistory.com/12 PUT, PATCH, DELETE
https://hjho95.tistory.com/11 POST 방식으로 PUT, PATCH, DELETE 사용하기

# ajax 시리즈의 참조 페이지.

@RequestParam: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
@ModelAttribute: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html
ajax settings: https://api.jquery.com/jquery.ajax/#jQuery-ajax-url-settings