form 데이터 전송 방법 중 GET 방식 막기

 

//	@RequestMapping(value="/register/save", method=RequestMethod.POST)
	@PostMapping("/register/save") // Spring 4.3 부터 추가
	public String save() {
		return "registerInfo";
	}
}

 

@GetMapping 추가

package com.jcy.usedhunter;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class RegisterController {
	
//	@RequestMapping("/register/add")
//	@RequestMapping(value="/register/save", method= {RequestMethod.GET, RequestMethod.POST})
	@GetMapping("/register/add")
	public String register() {
		return "registerForm";
	}
	
//	@RequestMapping(value="/register/save", method=RequestMethod.POST)
	@PostMapping("/register/save") // Spring 4.3 부터 추가
	public String save() {
		return "registerInfo";
	}
}

 

 

"/register/save" 를 @PostMapping 으로 매핑했기 때문에

이제 Get 방식으로 요청해도 안된다

 

 

@GetMapping 대신 view-controller 사용하기

 

servlet-context.xml 에 코드 추가

view-controller 를 사용하면 기존에 RegisterController 에서 사용한 @GetMapping 은 사용하면 안 된다.

<view-controller path="/register/add" view-name="registerForm"/>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
    <view-controller path="/register/add" view-name="registerForm"/>
	<context:component-scan base-package="com.usedhunter.app" />
	
	
	
</beans:beans>

 

mvc 스키마는 생략한 상태

xmlns:?? 많은 설정 중에 오직 하나만 생략가능하다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<mvc:annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<mvc:resources mapping="/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
    
	<mvc:view-controller path="/register/add" view-name="registerForm"/>
	<context:component-scan base-package="com.usedhunter.app" />
	
	
	
</beans:beans>

 

 

유효성 검사

 

msg 를 그대로 브라우저에 보내면 깨지기 때문에 URLEncoder 를 사용하자


package com.jcy.usedhunter;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class RegisterController {
	
//	@RequestMapping("/register/add")
//	@RequestMapping(value="/register/save", method= {RequestMethod.GET, RequestMethod.POST})
	@GetMapping("/register/add")
	public String register() {
		return "registerForm";
	}
	
//	@RequestMapping(value="/register/save", method=RequestMethod.POST)
	@PostMapping("/register/save") // Spring 4.3 부터 추가
	public String save(User user, Model m) throws Exception {
		
		// 1. 유효성 검사
		if(!isValid(user)) {
			String msg = URLEncoder.encode("id를 잘못입력하셨습니다.", "utf-8");
			return "redirect:/register/add?msg="+msg; // URL 재작성(rewriting)
		}
		
		
		// 2. DB에 신규회원 정보를 저장
		return "registerInfo";
	}

private boolean isValid(User user) {
	// TODO Auto-generated method stub
	return false;
}
}

 

간단하게 도메인 User 클래스를 만들자

package com.jcy.usedhunter;

public class User {

	private String id;
	private String pwd;
	private String name;
	private String email;
	private String birth;
	private String sns;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getBirth() {
		return birth;
	}
	public void setBirth(String birth) {
		this.birth = birth;
	}
	public String getSns() {
		return sns;
	}
	public void setSns(String sns) {
		this.sns = sns;
	}
	
	@Override
	public String toString() {
		return "User [id=" + id + ", pwd=" + pwd + ", name=" + name + ", email=" + email + ", birth=" + birth + ", sns="
				+ sns + "]";
	}
	
	
}

 

registerForm.jsp 에 msg 를 받는 코드를 추가

<div id="msg" class="msg">${param.msg}</div>

msg 가 출력 되지 않으면 decoder 추가

java.net.URLDecoder 를 import 해야함

<%@ page import="java.net.URLDecoder" %>
<div id="msg" class="msg">${URLDecoder.decode(param.msg)}</div>

 

registerFrom.jsp

 

form 태그에 action, method, onsubmit 을 추가

<form action="<c:url value="/register/save"/>" method="POST" onsubmit="return formCheck(this)">

javascript 에서 msg EL 을 따옴표로 묶어준다

function setMessage(msg, element){
            document.getElementById("msg").innerHTML = `<i class="fa fa-exclamation-circle"> ${'${msg}'}</i>`;
            if(element) {
                element.select();
            }
       }
<%@ page contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.net.URLDecoder" %>
<%@ page session="false" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" />
    <style>
        * { box-sizing:border-box; }
        form {
            width:400px;
            height:600px;
            display : flex;
            flex-direction: column;
            align-items:center;
            position : absolute;
            top:50%;
            left:50%;
            transform: translate(-50%, -50%) ;
            border: 1px solid rgb(89,117,196);
            border-radius: 10px;
        }
        .input-field {
            width: 300px;
            height: 40px;
            border : 1px solid rgb(89,117,196);
            border-radius:5px;
            padding: 0 10px;
            margin-bottom: 10px;
        }
        label {
            width:300px;
            height:30px;
            margin-top :4px;
        }
        button {
            background-color: rgb(89,117,196);
            color : white;
            width:300px;
            height:50px;
            font-size: 17px;
            border : none;
            border-radius: 5px;
            margin : 20px 0 30px 0;
        }
        .title {
            font-size : 50px;
            margin: 40px 0 30px 0;
        }
        .msg {
            height: 30px;
            text-align:center;
            font-size:16px;
            color:red;
            margin-bottom: 20px;
        }
        .sns-chk {
            margin-top : 5px; 
        }
    </style>
    <title>Register</title>
</head>
<body>
   <form action="<c:url value="/register/save"/>" method="POST" onsubmit="return formCheck(this)">
    <div class="title">Register</div>
    <!-- <div id="msg" class="msg">${param.msg}</div>  -->
    <div id="msg" class="msg">${URLDecoder.decode(param.msg)}</div>
    <label for="">아이디</label>
    <input class="input-field" type="text" name="id" placeholder="8~12자리의 영대소문자와 숫자 조합" autofocus>
    <label for="">비밀번호</label>
    <input class="input-field" type="text" name="pwd" placeholder="8~12자리의 영대소문자와 숫자 조합">
    <label for="">이름</label>
    <input class="input-field" type="text" name="name" placeholder="홍길동">
    <label for="">이메일</label>
    <input class="input-field" type="text" name="email" placeholder="jcy8206@google.com"> 
    <label for="">생일</label>
    <input class="input-field" type="text" name="birth" placeholder="2020/12/31">
    <div class="sns-chk">
        <label><input type="checkbox" name="sns" value="facebook"/>페이스북</label>
        <label><input type="checkbox" name="sns" value="kakaotalk"/>카카오톡</label>
        <label><input type="checkbox" name="sns" value="instagram"/>인스타그램</label>
    </div>
    <button>회원 가입</button>
   </form> 
   <script>
       function formCheck(frm) {
            var msg ='';
            if(frm.id.value.length<3) {
                setMessage('id의 길이는 3이상이어야 합니다.', frm.id);
                return false;
            }
           return true;
       }
       function setMessage(msg, element){
            document.getElementById("msg").innerHTML = `<i class="fa fa-exclamation-circle"> ${'${msg}'}</i>`;
            if(element) {
                element.select();
            }
       }
   </script>
</body>
</html>

 

 

Model 에 저장해서 넘기기

 

model 은 redirect 해서 요청하는 "register/add" 에서는 쓸 수 없고

mapping 한 "register/save" 에서만 사용가능 하다.

 

하지만 이를 Spring 에서 

"redirect:/register/add?msg="+msg;

이런 형태로 만들어 주기 때문에 잘 작동된다.

package com.jcy.usedhunter;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class RegisterController {
	
//	@RequestMapping("/register/add")
//	@RequestMapping(value="/register/save", method= {RequestMethod.GET, RequestMethod.POST})
	@GetMapping("/register/add")
	public String register() {
		return "registerForm";
	}
	
//	@RequestMapping(value="/register/save", method=RequestMethod.POST)
	@PostMapping("/register/save") // Spring 4.3 부터 추가
	public String save(User user, Model m) throws Exception {
		
		// 1. 유효성 검사
		if(!isValid(user)) {
			
			String msg = URLEncoder.encode("id를 잘못입력하셨습니다.", "utf-8");
			m.addAttribute("msg", msg);
			
//			return "redirect:/register/add?msg="+msg; // URL 재작성(rewriting)
			return "redirect:/register/add";
		}
		
		
		// 2. DB에 신규회원 정보를 저장
		return "registerInfo";
	}

private boolean isValid(User user) {
	// TODO Auto-generated method stub
	return false;
}
}

 

 

이제 isvalid 값을 true 로 바꿔 registerInfo 로 데이터가 잘 들어가는 지 확인하자

 

registerInfo.jsp 의 EL인 param 을 user로 바꾸자

<%@ 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>
<h1>id=${user.id}</h1>
<h1>pwd=${user.pwd}</h1>
<h1>name=${user.name}</h1>
<h1>email=${user.email}</h1>
<h1>birth=${user.birth}</h1>
<h1>sns=${user.sns}</h1>



</body>
</html>
private boolean isValid(User user) {
	// TODO Auto-generated method stub
	return true;
}

 

복사했습니다!