Coding/spring
부트스트랩 이용해서 에러메세지 띄워보기
찡콩찡
2022. 9. 23. 15:52
package com.exam.myapp;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor //여기에 필드에 쓴 모든 생성자만 만들어줌
@Setter
@Getter
public class CodeVo {
private String id;
private String title;
}
package com.exam.myapp;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter //lombok을 이용하여, 클래스의 모든 필드(멤버 변수)의 getXxx() 메서드 자동생성
// lombok을 이용하여, 클래스의 final이 아닌 모든 필드(멤버 변수)의 setXxx() 메서드 자동생성
public class TestVo {
//파라미터를 받는다고 할때 파라미터 변수랑 같은 이름이 있어야 함
private int x;
private int y;
private String lunch; //단일선택 변수저장
private String dinner;
//선택한 음식을 받을 수 있는 변수를 선언한다.
//요청파라미터값과 변수명이 같아야 받아진다.
private List<String> food = new ArrayList<String>(); //String[] e다중선택 변수 저장
private List<LicenseVO> license;
}
controller에 lunch와 Dinner에 대한 메서드 만들기
@RequestMapping(path="/param.do") //param.do로 요청을 보내면 아래 메서드 실행하자
public String param(Model model) {
List<CodeVo> list = new ArrayList<CodeVo>();
list.add(new CodeVo("f001", "피자"));
list.add(new CodeVo("f002", "햄버거"));
list.add(new CodeVo("f003", "스파게티"));
model.addAttribute("codeList",list);
TestVo vo = new TestVo();
vo.setLunch("f002");
vo.setDinner("f001");
List<String> list2 = new ArrayList<String>();
list2.add("f001");
list2.add("f003");
vo.setFood(list2);
model.addAttribute("testVo", vo);
return "param";
}
미션! jsp파일에 아래의 문제를 구현하기
<body>
<form action=""> 점심식사 :
<!-- 라디오버튼으로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 lunch의 음식이 선택되어있도록 구현 -->
<br/>
저녁식사 :
<!-- 셀렉트로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 Dinner의 음식이 선택되어있도록 구현 -->
<br/>
좋아하는 음식들 :
<!-- 페크박스로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 food의 음식이 선택되어있도록 구현 -->
<br/>
</form>
</body>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>스프링 폼 태그 연습</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.6.0.js"></script>
</head>
<body>
<form action="">
점심식사 :
<!-- 라디오버튼으로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 lunch의 음식이 선택되어있도록 구현 -->
<!-- 이렇게 작성하면 값이 바뀔때마다 하나하나 작성해야 해서 어려움!
<input type='radio' name='lunch' value='f001' id="lunch1"/><label for="lunch1">피자</label>
<input type='radio' name='lunch' value='f002' id="lunch2" checked="checked"/><label for="lunch2">햄버거</label>
<input type='radio' name='lunch' value='f003' id="lunch3"/><label for="lunch3">스파게티</label> -->
<c:forEach var="code" items="${codeList}" varStatus="stat">
<input type="radio" name="lunch" value="${code.id}" ${code.id==testVo.lunch?'checked':''} <%-- <c:if test="${code.id==testVo.lunch}">checked</c:if> 아래문장과 같음 --%>
id="lunch${stat.count}"/><label for="lunch${stat.count}">${code.title}</label>
</c:forEach>
<br/>
저녁식사 :
<!-- 셀렉트로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 Dinner의 음식이 선택되어있도록 구현 -->
<!-- <select name="dinner">
<option value="f001" selected="seelcted">피자</option>
<option value="f002">햄버거</option>
<option value="f003">스파게티</option>
</select> -->
<select name="dinner">
<c:forEach var="code" items="${codeList}">
<option value="${code.id}" ${code.id==testVo.dinner?'selected':''} >${code.title}</option>
</c:forEach>
</select>
<br/>
좋아하는 음식들 :
<!-- 체크박스로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 food의 음식이 선택되어있도록 구현 -->
<!-- <input type="checkbox" name="food" value="f001"/>피자
<input type='checkbox' name='food' value='f002' />햄버거
<input type='checkbox' name='food' value='f003' />스파게티 -->
<c:forEach var="code" items="${codeList}" varStatus="stat">
<input type="checkbox" name="food" value="${code.id}" ${testVo.food.contains(code.id)? 'checked':''} id="food${stat.index}"/><label for="food${stat.index}">${code.title}</label>
</c:forEach>
<br/>
<input type="submit"/>
</form>
</body>
</html>
spring form tag 위에 작성한 코드를 form 코드로 변경해보자
<form:form modelAttribute="testVo">
<form:radiobuttons path="lunch" items="${codeList}" itemValue="id" itemLabel="title"/>
</form:form>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 스프링 폼 태그 사용을 위한 태그 라이브러리 -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>스프링 폼 태그 연습</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.6.0.js"></script>
</head>
<body>
<h2>스프링 폼 태그 사용</h2>
<%-- <form:form>태그 내부의 입력 요소들이 사용할 값을 담고 있는 --%>
<!-- 모델 객체의 이름을 modelAtrribute 속성값으로 지정 -->
<form:form modelAttribute="testVo" action="${pageContext.request.contextPath}/param.do">
<!-- 각 입력요소의 값으로 사용할 모델 객체의 속성이름을 path 속성값으로 지정 -->
점심식사:
<form:radiobuttons path="lunch" items="${codeList}" itemValue="id" itemLabel="title"/>
<br/>
저녁식사:
<form:select path="dinner" items="${codeList}" itemValue="id" itemLabel="title"/>
<br/>
좋아하는 음식들:
<form:checkboxes path="food" items="${codeList}" itemValue="id" itemLabel="title"/>
<br/>
<input type="submit" />
</form:form>
<h2>스프링 폼 태그 미사용</h2>
<form action="" method="post">
점심식사 :
<!-- 라디오버튼으로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 lunch의 음식이 선택되어있도록 구현 -->
<!-- 이렇게 작성하면 값이 바뀔때마다 하나하나 작성해야 해서 어려움!
<input type='radio' name='lunch' value='f001' id="lunch1"/><label for="lunch1">피자</label>
<input type='radio' name='lunch' value='f002' id="lunch2" checked="checked"/><label for="lunch2">햄버거</label>
<input type='radio' name='lunch' value='f003' id="lunch3"/><label for="lunch3">스파게티</label> -->
<c:forEach var="code" items="${codeList}" varStatus="stat">
<input type="radio" name="lunch" value="${code.id}" ${code.id==testVo.lunch?'checked':''} <%-- <c:if test="${code.id==testVo.lunch}">checked</c:if> 아래문장과 같음 --%>
id="lunch${stat.count}"/><label for="lunch${stat.count}">${code.title}</label>
</c:forEach>
<br/>
저녁식사 :
<!-- 셀렉트로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 Dinner의 음식이 선택되어있도록 구현 -->
<!-- <select name="dinner">
<option value="f001" selected="seelcted">피자</option>
<option value="f002">햄버거</option>
<option value="f003">스파게티</option>
</select> -->
<select name="dinner">
<c:forEach var="code" items="${codeList}">
<option value="${code.id}" ${code.id==testVo.dinner?'selected':''} >${code.title}</option>
</c:forEach>
</select>
<br/>
좋아하는 음식들 :
<!-- 체크박스로 codeList에 있는 음식을 선택할 수 있도록 구현 -->
<!-- 현재 TestVo의 food의 음식이 선택되어있도록 구현 -->
<!-- <input type="checkbox" name="food" value="f001"/>피자
<input type='checkbox' name='food' value='f002' />햄버거
<input type='checkbox' name='food' value='f003' />스파게티 -->
<c:forEach var="code" items="${codeList}" varStatus="stat">
<input type="checkbox" name="food" value="${code.id}" ${testVo.food.contains(code.id)? 'checked':''} id="food${stat.index}"/><label for="food${stat.index}">${code.title}</label>
</c:forEach>
<br/>
<input type="submit"/>
</form>
</body>
</html>
회원가입도 form태그 이용해서 해보자
<div class="container">
<div class="row">
<div class="col">
<h1>회원등록</h1>
<form:form modelAttribute="memberVo" id="memForm" action="${pageContext.request.contextPath}/member/add.do" method="post">
<div class="mb-3">
<form:label path="memId" class="form-label">아이디</form:label>
<div class="input-group">
<form:input path="memId" class="form-control"/>
<button type="button" id="dupBtn" class="btn btn-primary">중복확인</button>
</div>
</div>
<div class="mb-3">
<form:label path="memPass" class="form-label">비밀번호</form:label>
<form:password path="memPass" class="form-control"/>
</div>
<div class="mb-3">
<label for="memPassCheck" class="form-label">비밀번호 확인</label>
<input type="password" class="form-control" id="memPassCheck">
</div>
<div class="mb-3">
<form:label path="memName" class="form-label">이름</form:label>
<form:input path="memName" class="form-control"/>
</div>
<div class="mb-3">
<form:label path="memPoint" class="form-label">포인트</form:label>
<form:input type="number" path="memPoint" class="form-control"/>
</div>
<button type="submit" id="saveBtn" class="btn btn-primary">저장</button>
<a href="${pageContext.request.contextPath}/member/list.do">
<button type="button" class="btn btn-primary"><i class="bi-file-plus-fill"></i>회원목록</button>
</a>
</form:form>
</div>
</div>
</div>
라이브러리 추가
<!-- 스프링에서 객체 검증을 위한 라이브러리 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.5.Final</version>
</dependency>
package com.exam.myapp.member;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class MemberVo {
@NotNull //이 변수의 값이 null값이 되어서는 안된다는 검증조건
@Size(max = 50, min = 1) //최소1글자, 최대 50글자 이하여야 한다는 검증 조건
private String memId;
@NotNull @Size(max = 50, min = 1)
private String memPass;
@NotNull @Size(max = 50, min = 1)
private String memName;
@Digits(integer =10, fraction = 0)
private int memPoint;
}
@RequestMapping(path = "add.do", method = RequestMethod.POST)
//@RequestMapping 메서드의 매개변수에 @Valid를 적용하면,
//해당 객체의 클래스에 지정한 검증조건에 맞는지 검증수행
//@Valid 매개변수뒤에 BindingResult (또는 Errors)타입의 매개변수를 추가하여,
//검증결과를 받아서 사용 가능
public String add(@Valid MemberVo vo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) { //검증결과 에러가 있다면
return "member/add"; //회원추가 jsp 화면을 다시 출력
}
int num = memberService.insert(vo);
return "redirect:/member/list.do";
}
비밀번호가 틀릴때
<div class="input-group">
<form:input path="memId" class="form-control"/>
<button type="button" id="dupBtn" class="btn btn-primary">중복확인</button>
<!-- 컨트롤러에서 검증 결과,
모델 객체의 memId속성값과 관련된 오류가 있는 경우 오류 메세지 출력 -->
<form:errors path="memId"/>
</div>
부트스트랩을 이용해서 오류메세지를 표현하고 싶다면 validation클릭
<div class="mb-3">
<form:label path="memId" class="form-label">아이디</form:label>
<div class="input-group">
<form:input path="memId" class="form-control" cssErrorClass="form-control is-invalid"/>
<button type="button" id="dupBtn" class="btn btn-primary">중복확인</button>
<!-- 컨트롤러에서 검증 결과,
모델 객체의 memId속성값과 관련된 오류가 있는 경우 오류 메세지 출력 -->
<form:errors path="memId" cssClass="invalid-feedback"/>
</div>
</div>
전체코드
<div class="col">
<h1>회원등록</h1>
<form:form modelAttribute="memberVo" id="memForm" action="${pageContext.request.contextPath}/member/add.do" method="post">
<div class="mb-3">
<form:label path="memId" class="form-label">아이디</form:label>
<div class="input-group">
<form:input path="memId" class="form-control" cssErrorClass="form-control is-invalid"/>
<button type="button" id="dupBtn" class="btn btn-primary">중복확인</button>
<!-- 컨트롤러에서 검증 결과,
모델 객체의 memId속성값과 관련된 오류가 있는 경우 오류 메세지 출력 -->
<form:errors path="memId" cssClass="invalid-feedback"/>
</div>
</div>
<div class="mb-3">
<form:label path="memPass" class="form-label" >비밀번호</form:label>
<form:password path="memPass" class="form-control" cssErrorClass="form-control is-invalid"/>
<form:errors path="memPass" cssClass="invalid-feedback"/>
</div>
<div class="mb-3">
<label for="memPassCheck" class="form-label">비밀번호 확인</label>
<input type="password" class="form-control" id="memPassCheck">
</div>
<div class="mb-3">
<form:label path="memName" class="form-label">이름</form:label>
<form:input path="memName" class="form-control" cssErrorClass="form-control is-invalid"/>
<form:errors path="memName" cssClass="invalid-feedback"/>
</div>
<div class="mb-3">
<form:label path="memPoint" class="form-label">포인트</form:label>
<form:input type="number" path="memPoint" class="form-control" cssErrorClass="form-control is-invalid"/>
<form:errors path="memPoint" cssClass="invalid-feedback"/>
</div>
<button type="submit" id="saveBtn" class="btn btn-primary">저장</button>
<a href="${pageContext.request.contextPath}/member/list.do">
<button type="button" class="btn btn-primary"><i class="bi-file-plus-fill"></i>회원목록</button>
</a>
</form:form>
</div>
에러 메세지가 마음에 들지 않아서 vo에 직접 작성해줄 때!
member.vo작성
@Digits(integer =10, fraction = 0,message = "최대 3자리 정수까지 입력가능")
private int memPoint;
서블릿에 errormessage를 등록해보자!
프로퍼터파일이 없어서 아래 경로로 파일을 만들어준다.
파일안에 "필수입력값입니다"를 작성해준다. 왜 아래와 같이 뜨는지는 모르겠다ㅠ
servelt-context 파일에 위치를 넣어주고 다시 실행해본다.
<!-- MessageSource 객체를 "messageSource"라는 이름으로 스프링에 등록하면,
해당 MessageSource 객체의 메세지들이 스프링에 등록되어 사용가능 -->
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 클래스패스 기준으로 메세지를 정의한 프로퍼터파일의 경로를 확장자 제외하고 지정 -->
<!-- message_en.properties, messag_ko.properties처럼 국가 및 언어 코드를 접미어로 붙인 파일들을 사용하면,
로케일에 따라서 다른 언어의 메세지들이 자동으로 사용되도록 설정 가능 -->
<beans:property name="basename" value="messages"/>
</beans:bean>