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>