17> 폼 유효성 체크
(1) 개요
- 사용자 입력 폼의 데이터 유효성 검사 의미.
ex>
필수사항(null허용 유무,...), 날짜(미래날짜만 가능), 값의 길이 n 개 이상, ....
(2) 구현 방식
- html 속성 이용
- JS 이용
==> html 및 JS 는 전부 클라이언트에서 처리하는 방법이다.
클라이언트에서 JS 비활성화 시키거나 보안 이슈 발생 가능성이 높음.
- Spring Boot 이용
==> 서버에서 유효성 체크하는 방법이다.
(3) 적용
가. 의존성 설정
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exam</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.webjars/bootstrap -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
나. DTO 생성 (Command Bean 이라고 하거나 form backing object:양식보조객체 라고도 함)
==> 변수에 어노테이션으로 유효성 조건을 지정한다.
public class MemberDTO {
String userid;
String username;
LocalDate targetDate;
// 생성자
// getter & setter
// toString
}
유효성 조건 지정
// Command Bean, Form backing object
public class MemberDTO {
@NotNull
String userid;
@Size(min = 3, message = "3글자 이상입니다.")
String username;
// 010-1234-4567 휴대폰 정규 표현식
// @Pattern(regexp = "/^\\d{3}-\\d{3,4}-\\d{4}$/")
// String phone;
@NotNull // 혼합도 가능(Not null 이면서 @FutureOrPresent 인 조건)
// @Future // 현재시간기준으로 미래날짜만설정
@FutureOrPresent(message = "현재 또는 미래의 날짜만 가능합니다.")
LocalDate targetDate;
// 생성자
// getter & setter
// toString
}
package com.exam.dto;
import java.time.LocalDate;
import javax.validation.constraints.FutureOrPresent;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
// Command Bean, Form backing Object
public class MemberDTO {
//@NotNull // null 금지
@NotEmpty(message = "userid 필수입니다.") // null, 빈문자열 금지
//@NotBlank // null 빈문자열 space 금지
String userid;
@Size(min = 3, message = "3글자 이상입니다.")
String username;
// 010-1234-4567
//@Pattern(regexp = "/^\\d{3}-\\d{3,4}-\\d{4}$/")
//String phone;
@NotNull
@FutureOrPresent(message = "현재 또는 미래의 날짜만 가능합니다.")
LocalDate targetDate;
public MemberDTO() {}
public MemberDTO(String userid, String username, LocalDate targetDate) {
this.userid = userid;
this.username = username;
this.targetDate = targetDate;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public LocalDate getTargetDate() {
return targetDate;
}
public void setTargetDate(LocalDate targetDate) {
this.targetDate = targetDate;
}
@Override
public String toString() {
return "MemberDTO [userid=" + userid + ", username=" + username + ", targetDate=" + targetDate + "]";
}
}
다. Controller 작업
- https://carrotweb.tistory.com/256 : Controller -> jsp 관련해서 참고했음.
- 양방향 적용(two-way binding)
Model 생성
Controller ----------------------------> jsp
<----------------------------
- GET 방식과 POST 방식 요청에 전부 Command Bean(DTO) 을 모델로 사용해야 된다.
화면요청(GET 방식)
Controller ----------------------------> jsp
<----------------------------
실제요청(POST 방식)
GET 방식
// 화면요청(get)
@GetMapping("/member")
public String memberForm(ModelMap m) {
MemberDTO dto = new MemberDTO();
// MemberDTO dto = new MemberDTO("aaa", "홍길동", LocalDate.now());
// m.addAttribute("memX", dto); // 임의의 값 지정하면 에러 발생
m.addAttribute("memberDTO", dto); // Command bean 으로 반드시 설정한다.
return "memberForm";
}
POST 방식
// 처리해주는 post 요청
@PostMapping("/member")
public String member(@Valid MemberDTO dto, BindingResult result) {
// @Valid 붙여야지만 유효성체크한것이 적용됨.
// BindingResult 가 에러발생 확인
System.out.println("MemberDTO" + dto);
if(result.hasErrors()) { // 에러가 발생시 실행
return "memberForm";
}
return "memberInfo";
}
package com.exam.controller;
import java.time.LocalDate;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.exam.dto.MemberDTO;
@Controller
public class MainController {
Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping("/member") // 화면요청
public String memberForm(ModelMap m) {
MemberDTO dto = new MemberDTO();
// MemberDTO dto = new MemberDTO("aaa","홍길동", LocalDate.now());
// m.addAttribute("memX", dto); // 임의의 값 지정하면 에러 발생
m.addAttribute("memberDTO", dto); // command bean으로 반드시 설정한다.
return "memberForm";
}
@PostMapping("/member") // 로직요청
public String member(@Valid MemberDTO dto, BindingResult result) {
System.out.println("MemberDTO" + dto);
if(result.hasErrors()) {
return "memberForm";
}
return "memberInfo";
}
}
memberForm.jsp
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<h2>회원가입폼</h2>
<form:form method="post" modelAttribute="memberDTO">
아이디: <form:input type="text" path="userid" />
<form:errors path="userid"></form:errors>
<br>
이름: <form:input type="text" path="username" />
<form:errors path="username"></form:errors>
<br>
날짜: <form:input type="date" path="targetDate" />
<form:errors path="targetDate"></form:errors>
<br>
<input type="submit" value="가입">
</form:form>
<%@ page
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
%>
<%@ taglib uri="http://www.springframework.org/tags/form"
prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>회원가입폼</h2>
<form:form method="post"
modelAttribute="memberDTO">
아이디:<form:input type="text" path="userid" />
<form:errors path="userid"></form:errors>
<br>
이름:<form:input type="text" path="username" />
<form:errors path="username"></form:errors>
<br>
날짜:<form:input type="date" path="targetDate" />
<form:errors path="targetDate"></form:errors>
<br>
<input type="submit" value="가입">
</form:form>
</body>
</html>
package com.exam;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
<%@ page
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
%>
<%@ taglib uri="http://www.springframework.org/tags/form"
prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>memberInfo</h2>
</body>
</html>
# application.properties
logging.level.org.springframework=info
# tomcat port 번호 변경
server.port=8090
# context 명 변경
server.servlet.context-path=/app
# jsp의 경로와 확장자 지정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
# LocalDate 타입의 날짜 포맷 지정
spring.mvc.format.date=yyyy-MM-dd
'[study]이론정리 > Spring Boot' 카테고리의 다른 글
Spring MVC - webjar (0) | 2024.07.03 |
---|---|
Spring MVC - 국제화(I18N: Internationalization) (0) | 2024.07.03 |
Spring MVC - 예외처리 (0) | 2024.07.03 |
Spring MVC - HandlerInterceptor (X 라고 가정) (0) | 2024.07.03 |
Spring MVC - FileUpload & download (0) | 2024.07.02 |