Jun's Blog
홈페이지 만들어보기[유효성체크](with SpringBoot) - (4) 본문
1. 유효성(vaildation) 추가하기
pom.xml에 추가한 부분(with. IntelliJ)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
위의 내용 추가 후, 아래의 갱신 작업을 수행
member.java에 추가 및 수정한 부분(with. IntelliJ)
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
@NotBlank(message = "이름은 필수 입력 사항입니다.")
private String name;
@Column(unique = true, nullable = false)
@NotBlank(message = "이메일은 필수 입력 사항입니다.")
@Email(message = "올바른 이메일 형식으로 입력해 주셔야 합니다.")
private String email;
@NotBlank(message = "비밀번호는 필수 입력 사항입니다.")
@Size(min = 8, max = 16, message = "비밀번호는 8자리 이상, 16자리 이하로 입력해 주세요.")
@Pattern(regexp = ".*[A-Z].*", message = "비밀번호는 대문자 1개 이상을 포함해야 합니다.")
@Pattern(regexp = ".*[!@#$%].*", message = "비밀번호는 특수 문자 '!@#$%' 중 하나 이상을 포함해야 합니다.")
private String password;
memberController.java에 추가 및 수정한 부분(with. IntelliJ)
import jakarta.validation.Valid;
@PostMapping("/signup")
public ResponseEntity<?> signup(@Valid @RequestBody Member member, BindingResult bindingResult){
// ResponseEntity : HTTP 응답 코드
// @RequestBody : JSON 형태의 문자열을 자바의 객체 형식으로 변환해 줍니다.
// @Valid : 유효성 검사를 수행하는 어노테이션입니다.
// BindingResult : 유효성 검사시 문제가 있으면 예외를 발생시켜 줍니다.
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
if(bindingResult.hasErrors()){
Map<String, String> errors = new HashMap<String, String>();
for(FieldError err : bindingResult.getFieldErrors()){
errors.put(err.getField(), err.getDefaultMessage());
}
// HttpStatus.BAD_REQUEST : 사용자가 잘못된 형식의 요청이 들어오는 경우에 많이 사용합니다.
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
유효성 에러 확인용 메세지 출력 설정
System.out.println("유효성 오류 갯수");
System.out.println(bindingResult.getFieldErrorCount());
Map<String, String> errors = new HashMap<String, String>();
for(FieldError err : bindingResult.getFieldErrors()){
errors.put(err.getField(), err.getDefaultMessage());
}
System.out.println(errors);
<유효성 검사 관련 실행 결과 - (1)>
테스트를 위해 React 부분의 Name에 대한 required 속성을 빼고 테스트합니다.
<Form.Group className="mb-3 d-flex align-items-center" controlId="forName">
<Form.Label className="me-3 d-flex align-items-center" style={{ whiteSpace: "nowrap" }}>이름</Form.Label>
<Form.Control
type="text"
placeholder="이름을(를) 입력해 주세요."
value={name}
onChange={(event) => {setName(event.target.value)}}
required
/>
<테스트 결과> - 400 Error 발생
<콘솔창 Error 메세지> - 이름 정보를 미입력하여 해당 Validation 으로 인한 오류로 확인
memberController.java에 추가 및 수정한 부분(with. IntelliJ)
const [errors, setErrors] = useState({
name: "", email: "", password: "", address: "", general: ""
});
}catch(error){
if(error.response && error.response.data){
setErrors(error.response.data); // 서버에서 받은 오류 메시지를 객체로 저장
}else{
// 다른 오류 메시지
setErrors(prevErrors => ({ ...prevErrors, general: "회원 가입 중 오류가 발생하였습니다." }));
}
}
{/* 일반 오류 메시지 표시 (예: 서버 오류) */}
{errors.general && <Alert variant="danger">{errors.general}</Alert>}
isInvalid={!!errors.name} // 오류가 있으면 빨간색 표시
<Form.Control.Feedback type="invalid">
{errors.name}
</Form.Control.Feedback>
isInvalid={!!errors.email}
<Form.Control.Feedback type="invalid">
{errors.email}
</Form.Control.Feedback>
isInvalid={!!errors.password}
<Form.Control.Feedback type="invalid">
{errors.password}
</Form.Control.Feedback>
isInvalid={!!errors.address}
<Form.Control.Feedback type="invalid">
{errors.address}
</Form.Control.Feedback>
memberController.java에 추가 및 수정완료한 전체 소스 내용(with. IntelliJ)
import { useState } from "react";
import { Alert, Button, Container, Form } from "react-bootstrap";
import axios from "axios";
// 특정한 페이지로 이동을 시킬 때 사용하는 hook
import { useNavigate } from "react-router-dom";
function App(){
console.log('회원 가입');
// 파라미터 관련 state 변수 선언
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [address, setAddress] = useState('');
const navigate = useNavigate();
// 예외 관련 state 변수 선언
// 오류 메시지 객체
const [errors, setErrors] = useState({
name: "", email: "", password: "", address: "", general: ""
});
const handleSingup = async (event) => {
event.preventDefault();
/* spring boot에게 post 방식으로 전달 */
try{
/* response는 응답 객체 */
const response = await axios.post(
"http://localhost:9000/member/signup",
{name, email, password, address}
);
// http 응답 코드 201은 요청 성공이고, 새로운 리소스 생성시 서버가 반환해주는 코드
if(response.status === 201){
alert('회원 가입 성공');
navigate('/member/login'); // 로그인 페이지로 이동
}
}catch(error){
if(error.response && error.response.data){
setErrors(error.response.data); // 서버에서 받은 오류 메시지를 객체로 저장
}else{
// 다른 오류 메시지
setErrors(prevErrors => ({ ...prevErrors, general: "회원 가입 중 오류가 발생하였습니다." }));
}
}
};
return(
<Container className="mt-5">
<h2 className="text-center mb-4">회원 가입</h2>
{/* 일반 오류 메시지 표시 (예: 서버 오류) */}
{errors.general && <Alert variant="danger">{errors.general}</Alert>}
<Form onSubmit={handleSingup}>
<Form.Group className="mb-3 d-flex align-items-center" controlId="forName">
<Form.Label className="me-3 d-flex align-items-center" style={{ whiteSpace: "nowrap" }}>이름</Form.Label>
<Form.Control
type="text"
placeholder="이름을(를) 입력해 주세요."
value={name}
onChange={(event) => {setName(event.target.value)}}
isInvalid={!!errors.name} // 오류가 있으면 빨간색 표시
/>
<Form.Control.Feedback type="invalid">
{errors.name}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3 d-flex align-items-center" controlId="forEmail">
<Form.Label className="me-3 d-flex align-items-center" style={{ whiteSpace: "nowrap" }}>이메일</Form.Label>
<Form.Control
type="text"
placeholder="이메일을(를) 입력해 주세요."
value={email}
onChange={(event) => {setEmail(event.target.value)}}
isInvalid={!!errors.email}
required
/>
<Form.Control.Feedback type="invalid">{errors.email}</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3 d-flex align-items-center" controlId="forPassword">
<Form.Label className="me-3 d-flex align-items-center" style={{ whiteSpace: "nowrap" }}>비밀 번호</Form.Label>
<Form.Control
type="password"
placeholder="비밀 번호을(를) 입력해 주세요."
value={password}
onChange={(event) => {setPassword(event.target.value)}}
isInvalid={!!errors.password}
required
/>
<Form.Control.Feedback type="invalid">{errors.password}</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3 d-flex align-items-center" controlId="forAddress">
<Form.Label className="me-3 d-flex align-items-center" style={{ whiteSpace: "nowrap" }}>주소</Form.Label>
<Form.Control
type="text"
placeholder="주소을(를) 입력해 주세요."
value={address}
onChange={(event) => {setAddress(event.target.value)}}
isInvalid={!!errors.address}
required
/>
<Form.Control.Feedback type="invalid">{errors.address}</Form.Control.Feedback>
</Form.Group>
<Button variant="primary" type="submit" className="w-100">
회원 가입
</Button>
</Form>
</Container>
);
}
export default App ;
<유효성 검사 관련 실행 결과 - (2)>
<테스트 결과> - 400 Error 발생
<콘솔창 Error 메세지> - 이름 정보를 미입력하여 해당 Validation 으로 인한 오류로 확인
'WEB > React' 카테고리의 다른 글
홈페이지 만들어보기[로그아웃](with SpringBoot) - (6) (1) | 2025.02.19 |
---|---|
홈페이지 만들어보기[로그인](with SpringBoot) - (5) (0) | 2025.02.19 |
홈페이지 만들어보기[회원가입](with SpringBoot) - (3) (1) | 2025.02.18 |
홈페이지 만들어보기[화면만들기](with SpringBoot) - (2) (0) | 2025.02.17 |
홈페이지 만들어보기[기본 구조 생성](with SpringBoot) - (1) (1) | 2025.02.17 |