우리가 Get매핑방식과 Post매핑방식의 uri가 같은 uri로 지정되있을때
get방식은 해당 뷰페이지를 출력시켜주며
Post방식은 출력된 뷰페이지로부터 전송을받습니다
뷰페이지의 form에서 action을 생략해도 알아서 찾아갑니다
<form method="post">
뷰페이지의 action url이 컨트롤러의 GET uri와 POST uri가 똑같으면 안써도됩니다.
action uri를 적지 않아도 form으로 요청을 발생시켜주는 페이지의 uri와 form으로부터 요청이 들어오는 uri가 같을때
뷰페이지로(화면)부터 요청이 들어오는 컨트롤러의 메서드 전송방식를 POST로 지정을 해놨다면 자동으로 POST방식의 해당 메서드로 잡혀 전송이됩니다.
uri가 동일하면서, GET과 POST로 나눠져 있다면 HandlerMapping의 uri정보수집에 의해서 시작과 끝이 같게 지정되는 느낌으로 처리되는것 같습니다.
따라서 기본적으로 POST방식은 데이터를 전달하거나 받는곳! 이라고 보면됩니다.
GET방식은 페이지 출력을 요청 하는곳! 으로 보면 되는것이죠
컨트롤러에 GET:/register , POST:/register 등록
GET방식은 페이지를 실행하여 뷰페이지 파일을 읽어 화면에 출력합니다.
POST방식은 뷰페이지 파일로부터 form전송을 통해 받게됩니다
@Controller
@RequestMapping("/score")
public class ScoreController {
@GetMapping("/register") //주소창에 뷰페이지를 띄울때 요청주소(시작)
public String register() {
System.out.println("/score/register : GET");
return "score/write-form";
}
@PostMapping("/register") //form으로부터 받을때 받는 주소(끝)
public String regester(ScoreVO scores) { //
System.out.println("/score/register : POST");
System.out.println("Controller Param : "+scores);
return "";
}
}
POST방식으로 전송하게되면 DispatcherServlet을 통해서 score URI를 찾아서 handdlerMapping을 통해
매핑주소가 /score와 /register라는 매핑주소에 등록된 정보를 수집하고 handlerAdapter가 해당 정보를통해 메서드들을 구분하여 호출합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>시험점수 등록</h2>
<form method="post"><!-- action="/web/score/register" -->
<p>
# 이름 : <input name="stuName" /> <br /><!-- text속성을 생략하면 자동으로 text박스생성 -->
# 국어 : <input name="kor" /> <br />
# 영어 : <input name="eng" /> <br />
# 수학 : <input name="math" /> <br />
<input type="submit" value="확인"/>
</p>
</form>
</body>
</html>
1.
주소창에 /register라고 입력하여 GET방식으로 메서드를 실행하여 write-form.jsp파일을 불러 화면에 출력합니다.
@GetMapping("/register") //주소창에 뷰페이지를 띄울때 요청주소(시작)
public String register() {
System.out.println("/score/register : GET");
return "score/write-form";
}
2.
write-form.jsp파일 에서 action을 비운 후 POST로 전송요청을 합니다
<form method="post">
3.
POST방식으로 선언된 동일한 uri인 /register 가 선언된 메서드로 자동으로 받아집니다.
@PostMapping("/register") //form으로부터 받을때 받는 주소(끝)
public String regester(ScoreVO scores) { //
System.out.println("/score/register : POST");
System.out.println("Controller Param : "+scores);
return "";
}
form태그의 action속성은 입력받은 데이터를 보내기위한 uri주소입니다
하지만 그게 비어있다면 받았던곳이랑 같은 매핑주소로 POST로 검색하여 있다면 해당 메서드로 보내줍니다.
action속성의 uri주소가 없다면 uri주소를 GET,POST공통으로 기준을 잡아서 즉, 시작과 끝의 uri주소를 동일하게 잡고 실행되는 것처럼 보입니다.
공부를 하다보니 추가적으로 또 재미난 사실이 있네요
만약 요청메서드에서 int타입 변수 no에 값을 담아 뷰페이지로 전송하고 해당 뷰페이지에서 <input type="hidden" name="no" /> 라는 hidden태그를 사용하여 본문내용에심은 후 form태그로 post방식의 전송을 요청하면 응답받는곳에서 해당 변수값을 받아와 사용할수 있게 됩니다.
주로 게시글번호를 기준으로 수정할때 수정 완료후 해당 게시글 내용으로 다시 돌아갈때 돌아가서 보여줄 게시글의 게시글번호값을 넘겨야합니다 바로 이렇게 hidden을 사용해서 처리합니다.
하지만 이게 신기하게 적용됩니다
만약 uri매핑주소가 같아 action을 생략할 수 있을때,
param.jsp 뷰페이지파일을 브라우저에 출력시켜주는 요청을 수행할 GetMapping의 uri주소를 /param ,
출력된 뷰페이지로 부터의 전송을 post방식으로 응답받을 PostMapping의 uri주소를 /param
이렇게 각각 동일한 uri로 지정했다고 가정해 봅니다.
이때, action속성을 생략한다면 자동으로 같은 uri 기준으로 인식후 해당 방식의 메서드를 찾아서 요청시작과 요청후 응답인 끝이 자동으로 연결되게 됩니다.
<input type="hidden"> 태그를 사용해서 해당 태그의 name파라미터에 이전으로부터 받은 값을 담아 넘길수 있습니다.
그치만 이렇게 GetMappin,PostMapping의 uri주소가 서로 같아 action을 생략할때
주소창에 파라미터를 넘기고 있었다면, 굳이 hidden태그를 사용하지 않아도 파라미터를 타고 값이 넘어가게 됩니다.
예제소스를 통해 확인합니다.
파라미터로 값을 넘깁니다
@GetMapping("/param.in")
public ModelAndView paramIn() {
int no = 1;
return new ModelAndView("redirect:/param","no",no);
}
no의 값을 최초로 넘기는 곳 이며, forwarding은 물론이고 redirect할때 파라미터로 값을 넘길때는 ModelAndView를 사용합니다. https://u-it.tistory.com/19?category=908594페이지 참조
1. 먼저 uri주소가 /param으로 지정된 param.jsp 뷰페이지 파일을 띄울 메서드를 정의하고
@GetMapping("/param")
public void param(@RequestParam("no") int no, Model m) {
}
/param.in 으로부터 no값을 받아와 실행했을때 받아온 no값을 Model과 유사한 기능으로 객체화하여 넘겨줍니다.
2. 값을 넘겨받은 페이지를 띄우고 이곳에서 get방식으로 받은 요청응답하고 다시 post방식으로 전송할수있도록
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post">
<%-- <input type="hidden" name="bno" value="${boardNo}" /> --%>
<h2>no : ${no}</h2> <br />
<input type="submit" value="파라미터 전송!" />
</form>
</body>
</html>
form 태그와 submit 전송버튼을 만듭니다. 이때 action속성은 생략합니다.
form으로부터 post방식으로 전송요청을 받게되는 메서드입니다.
@PostMapping("/param")
public String param(@ModelAttribute("no") int no) {
return "redirect:/param.out?no="+no;
}
이곳에서 받은 int no변수는 form태그로부터 전송받은 변수가 아닙니다.
결과를 띄울 뷰페이지창을 간단히 컨트롤러에 코드합니다.
@GetMapping("/param.out")
public void paramOut(int no , HttpServletResponse res) {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = res.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Parameter 예제</title>");
out.println("</head>");
out.println("<body>");
out.println("/paramReq,/paramRes로 부터 받은 파라미터 no : "+no);
out.println("</body>");
out.println("</html>");
}
파라미터값을 정상적으로 받게됩니다.
파라미터로만 받을수 있는 이유
HandlerMapping은 /uri 주소의 메서드전송방식 , 파라미터 등의 uri의 정보를 받아오게되죠?
만약 동일한 PostMapping에도 동일한 매핑주소가 선언되있다면 HandlerMapping이 검색한 uri주소는 한개이기에
두가지의 정보를 다 받을것이라 추측됩니다.
파라미터가아닌 다른방식으로 받으면 안되는이유
Model을 포함하여 Model객체의 addttribute()기능을 가진@RequestParam, @ModelAttribute 혹은 RedirectAttribute객체의 addAttribute(),addFlashAttribute() 의 기능은 "키","값" 쌍으로 객체에 담아 객체를 통으로 전송시켜줍니다. (addFlash는 객체를 서버에 저장후 꺼내서 씁니다)
이 방법은 URL 즉 파라미터를 통해 전송되는 방법이아니고 Header(헤더)에 포함하여 전송하는 방법입니다.
HandlerMapping은 객체정보를 얻을수는 없는것 같습니다.
정리하자면
GetMapping과 PostMapping 각각의 uri주소가 같아 form태그의 action속성을 생략했을 때, 우선 알아서 찾아가게되는데 이때에는 HandlerMapping이 uri의 정보를 수집하게되며 이때 HandlerMappin은 GetMapping과 PostMapping에 동일한 uri가 등록되었기때문에 해당 uri에대한 정보로 각각 GetMapping정보, PostMapping정보를 함께 수집하게됩니다.
HandlerMapping : "음.. 이 uri는 Get방식으로 받는 메서드가있구나!, 어? Post방식으로 받는 메서드도 있네? 오케이 두가지를 다하는구나 그럼 Get Post 둘다 수집!"
이렇게 GET과 POST를 연결해줌은 물론 파라미터정보가 공유되어 수집되있기 때문에 Post에서 parameter정보를 얻으려한다면 Get으로부터 얻을수 있게되는것입니다.
단, 이때 JSP에서 action속성에 같은 uri주소를 작성하면 bno의값이 null값으로 인식되니까 객체화 해달라는? 오류가 발생하며 작동이 안되니 이렇게 사용하실때에는 action주소는 무조건 생략하시기 바랍니다.
아~ 어렵고 복잡하고 재밌다~