
| 커스텀 태그 | 설명 |
|---|---|
<form:form> | <form>태그를 생성할 때 사용action : 폼 데이터를 전송할 URL을 입력 enctype : 전송될 데이터의 인코딩 타입 method : 전송 방식 |
<form:input> | text 타입의 <input> 태그path : 바인딩 될 커맨드 객체의 프로퍼티 지정 value : path 속성에서 지정한 커맨드 객체의 프로퍼티 값 출력 |
<form:password> | password 타입의 <input> 태그path : 바인딩 될 커맨드 객체의 프로퍼티 지정 value : path 속성에서 지정한 커맨드 객체의 프로퍼티 값 출력 |
<form:hidden> | hidden 타입의<input> 태그path : 바인딩 될 커맨드 객체의 프로퍼티 지정 value : path 속성에서 지정한 커맨드 객체의 프로퍼티 값 출력 |
<form:select> | <select> 태그를 생성. <option> 태그를 생성하는 데 필요한 콜렉션을 전달 받을 수도 있음 |
<form:options> | 지정한 콜렉션 객체를 이용하여 <option> 태그를 생성ex) <form:options items=”${jobCodes}” itemLabel=”label” itemValue=”code”/> |
<form:option> | 한 개의 <option> 태그를 생성 |
<form:checkboxes> | 커맨드 객체의 특정 프로퍼티와 관련된 checkbox 타입의 <input> 태그 목록을 생성ex) <form:checkboxes items=”${favoriteOsNames}” path=”favoriteOs”/> |
<form:checkbox> | 커맨드 객체의 특정 프로퍼티와 관련된 한 개의 checkbox 타입 <input> 태그를 생성 |
<form:radiobuttons> | 커맨드 객체의 특정 프로퍼티와 관련된 radio 타입의 <input> 태그 목록을 생성ex) <form:radiobuttons items=”${tools}” path=”tool”/> |
<form:radiobutton> | 커맨드 객체의 특정 프로퍼티와 관련된 한 개의 radio 타입 <input> 태그를 생성 |
<form:textarea> | <textarea> 태그를 위한 커스텀 태그 |
| 속성 | 설명 |
|---|---|
| cssClass | HTML의 class 속성값 |
| cssErrorClass | 폼 검증 에러가 발생했을 때 사용할 HTML의 class 속성값 |
| cssStyle | HTML의 style 속성값 |
package kr.spring.ch08.validator;
import kr.spring.ch08.model.Address;
import kr.spring.ch08.model.MemberInfo;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class MemberInfoValidator implements Validator {
@Override
//Validator가 해당 클래스에 대한 값 검증을 지원하는 지의 여부를 리턴
public boolean supports(Class<?> clazz) {
return MemberInfo.class.isAssignableFrom(clazz);
}
@Override
//target 객체에 대한 검증을 실행한다. 검증 결과 문제가 있을 경우 errors 객체에
//어떤 문제인지에 대한 정보를 저장한다.
public void validate(Object target, Errors errors) {
MemberInfo memberInfo = (MemberInfo) target;
if (memberInfo.getId() == null || memberInfo.getId().trim().isEmpty()) {
errors.rejectValue("id", "required");
}
if (memberInfo.getName() == null
|| memberInfo.getName().trim().isEmpty()) {
errors.rejectValue("name", "required");
}
if (memberInfo.getAddress() == null
|| memberInfo.getAddress().trim().isEmpty()) {
errors.rejectValue("address", "required");
}
}
}
국제화 지원을 위해 org.springframework.context.MessageSource 인터페이스를 제공
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<value>message.greeting</value>
</property>
</bean>
reject() 메서드를 이용하여 커맨드 객체 자체에 대한 에러 코드를 입력한 경우, 다음의 순서로 메시지 코드를 생성
1) 에러코드 + “.” + 커맨드 객체 이름
2) 에러코드
rejectValue() 메서드를 이용하여 특정 필드에 대한 에러 코드를 입력했다면, 다음의 순서로 메시지 코드를 생성
1)에러코드 + “.” + 커맨드 객체 이름 + “.” + 필드명
2)에러코드 + “.” + 필드명
3)에러코드 + “.” + 필드 타입
4)에러코드
예시
1) required.loginCommand.userId
2) required.userId
3) required.java.lang.String
4) required
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800" /><!-- 50M -->
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>
CommonsMultipartResolver 클래스의 프로퍼티
| 프로퍼티 | 타입 | 설명 |
|---|---|---|
| maxUploadSize | long | 최대 업로드 가능한 바이트 크기, -1은 제한이 없음을 의미한다. 기본값은 -1이다. |
| maxInMemorySize | int | 디스크에 임시 파일을 생성하기 전에 메모리에 보관할 수 있는 최대 바이트 크기. 기본값은 10240 바이트이다. |
| defaultEncoding | String | 요청을 파싱할 때 사용할 캐릭터 인코딩. 지정하지 않을 경우, HttpServletRequest.setCharacterEncoding() 메서드로 지정한 캐릭터 셋이 사용된다. 아무 값도 없을 경우 ISO-8859-1을 사용한다. |
try {
File file = new File(path + "/" + command.getReportFile().getOriginalFilename());
command.getReportFile().transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
package kr.spring.ch05.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class GameSearchController {
@RequestMapping("/search/main.do")
public String main() {
// 뷰 이름 지정
return"search/main";
}
}
<beans:bean class="kr.spring.ch05.controller.GameSearchController"/>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게임 검색 메인</title>
</head>
<body>
<form action="game.do" method="get">
<select name="type">
<option value="1">전체</option>
<option value="2">아이템</option>
<option value="3">캐릭터</option>
</select>
<input type="search" name="query">
<input type="submit" value="검색">
</form>
</body>
</html>

package kr.spring.ch05.vo;
public class SearchVO {
private int type;
private String query;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
@Override
public String toString() {
return "SearchVO [type=" + type + ", query=" + query + "]";
}
}
package kr.spring.ch05.service;
import kr.spring.ch05.vo.SearchVO;
public class SearchService {
public String search(SearchVO vo) {
System.out.println(vo);
return "검색 완료!";
}
}
package kr.spring.ch05.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import kr.spring.ch05.service.SearchService;
import kr.spring.ch05.vo.SearchVO;
@Controller
public class GameSearchController {
@Autowired
private SearchService searchService;
@RequestMapping("/search/main.do")
public String main() {
// 뷰 이름 지정
return"search/main";
}
@RequestMapping("/search/game.do")
public ModelAndView search(@ModelAttribute("vo") SearchVO searchVO) {
System.out.println("검색어 = " + searchVO.getQuery());
String result = searchService.search(searchVO);
ModelAndView mav = new ModelAndView();
// 뷰 이름 지정하기
mav.setViewName("search/game");
// 뷰에서 사용할 데이터 저장
mav.addObject("searchResult",result);
return mav;
}
}
<!-- 파라미터로 전달된 데이터를 자바빈에 담기 -->
<beans:bean class="kr.spring.ch05.controller.GameSearchController"/>
<beans:bean class="kr.spring.ch05.service.SearchService"/>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>검색 결과</title>
</head>
<body>
${searchResult }
</body>
</html>

혼자 작성해본 코드
package kr.spring.ch06.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import kr.spring.ch06.service.AccountService;
import kr.spring.ch06.vo.AccountVO;
@Controller
public class CreateAccountController {
@Autowired
private AccountService accountService;
// 폼 호출하기
@GetMapping("/account/create.do")
public String form() {
return "account/creationForm";
}
@PostMapping("/account/create.do")
public ModelAndView post(@ModelAttribute AccountVO vo) {
System.out.println("아이디 = " + vo.getId());
System.out.println("이름 = " + vo.getName());
System.out.println("우편번호 = " + vo.getZipcode());
System.out.println("주소 = " + vo.getAddress1());
System.out.println("상세 주소 = " + vo.getAddress2());
String msg = accountService.create(vo);
ModelAndView mav = new ModelAndView();
// 뷰 이름 지정하기
mav.setViewName("account/created");
// 뷰에서 사용할 데이터 저장
mav.addObject("msg",msg);
return mav;
}
}
package kr.spring.ch06.vo;
public class AccountVO {
private String id;
private String name;
private String zipcode;
private String address1;
private String address2;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
@Override
public String toString() {
return "AccountVO [id=" + id + ", name=" + name + ", zipcode=" + zipcode + ", address1=" + address1
+ ", address2=" + address2 + "]";
}
}
package kr.spring.ch06.service;
import kr.spring.ch06.vo.AccountVO;
public class AccountService {
public String create(AccountVO vo) {
System.out.println(vo);
return "회원가입이 완료되었습니다!";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입 완료</title>
</head>
<body>
${msg }
</body>
</html>

강사님 코드
package kr.spring.ch06.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import kr.spring.ch06.vo.MemberVO;
@Controller
public class CreateAccountController {
// 폼 호출하기
@GetMapping("/account/create.do")
public String form() {
return "account/creationForm";
}
// 폼 등록하기
@PostMapping("/account/create.do")
public String submit(MemberVO vo) {
System.out.println(vo);
return "account/created";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입 완료</title>
</head>
<body>
회원 가입이 완료되었습니다
<ul>
<li>아이디 : ${memberVO.id }</li>
<li>이름 : ${memberVO.name }</li>
<li>우편번호 : ${memberVO.zipcode }</li>
<li>주소 : ${memberVO.address1 } ${memberVO.address2 }</li>
</ul>
</body>
</html>

유효성 체크하기
package kr.spring.ch06.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import kr.spring.ch06.vo.MemberVO;
public class MemberValidator implements Validator{
// Valdator가 검증할 수 있는 타입인지를 검사
@Override
public boolean supports(Class<?> clazz) {
// 유효성 검사를 진행하는 객체가 java bean의 형태인지 확인
return MemberVO.class.isAssignableFrom(clazz);
}
// 유효성 체크를 실질적으로 수행하는 메서드
// target : 검증하는 자바빈(VO) 객체
// errors : 예외의 정보를 담는 객체
@Override
public void validate(Object target, Errors errors) {
MemberVO vo = (MemberVO)target;
if(vo.getId() == null || vo.getId().trim().isEmpty()) {
// 필드 에러코드 에러 문구
errors.rejectValue("id", null, "ID는 필수 항목입니다.");
}
if(vo.getName() == null || vo.getName().trim().isEmpty()) {
errors.rejectValue("name", null, "이름은 필수 항목입니다.");
}
if(vo.getZipcode() == null || vo.getZipcode().trim().isEmpty()) {
errors.rejectValue("zipcode", null, "우편번호는 필수 항목입니다.");
}
if(vo.getAddress1() == null || vo.getAddress1().trim().isEmpty()) {
errors.rejectValue("address1", null, "주소는 필수 항목입니다.");
}
if(vo.getAddress2() == null || vo.getAddress2().trim().isEmpty()) {
errors.rejectValue("address2", null, "상세 주소는 필수 항목입니다.");
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입</title>
</head>
<body>
<form:form action="create.do" modelAttribute="command">
아이디 : <form:input path="id"/>
<form:errors path="id"/>
<br>
이름: <form:input path="name"/>
<form:errors path="name"/>
<br>
우편번호 : <form:input path="zipcode"/>
<form:errors path="zipcode"/>
<br>
주소 : <form:input path="address1"/>
<form:errors path="address1"/>
<br>
상세 주소 : <form:input path="address2"/>
<form:errors path="address2"/>
<br>
<form:button>전송</form:button>
</form:form>
</body>
</html>
package kr.spring.ch06.controller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import kr.spring.ch06.validator.MemberValidator;
import kr.spring.ch06.vo.MemberVO;
@Controller
public class CreateAccountController {
// 유효성 체크할 경우 form:form태그에 자바빈을 지정해야 하기 때문에
// 폼이 호출 되기 전에 자바빈을 생성해서 전달
// 자바빈 초기화
@ModelAttribute("command")
public MemberVO initCommand() {
return new MemberVO();
}
// 폼 호출하기
@GetMapping("/account/create.do")
public String form() {
return "account/creationForm";
}
// 폼 등록하기
@PostMapping("/account/create.do")
public String submit(@ModelAttribute("command")MemberVO vo, BindingResult result) {
System.out.println(vo);
// 전송된 데이터 유효성 체크
// 자바빈 , binding result 저장
new MemberValidator().validate(vo, result);
// BindingResult에 유효성 체크 결과 오류에 대한 내용이 저장되어 있으면
// 폼을 다시 호출한다
if(result.hasErrors()) {
return "account/creationForm";
}
return "account/created";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 가입 완료</title>
</head>
<body>
회원 가입이 완료되었습니다
<ul>
<li>아이디 : ${command.id }</li>
<li>이름 : ${command.name }</li>
<li>우편번호 : ${command.zipcode }</li>
<li>주소 : ${command.address1 } ${command.address2 }</li>
</ul>
</body>
</html>
# 에러 코드 = 에러 문구
required = 필수 항목입니다.
<!-- validation.properties 설정하기 (resource-bundel) -->
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<!-- 폴더명 . 파일명 -->
<beans:value>messages.validation</beans:value>
</beans:list>
</beans:property>
</beans:bean>
package kr.spring.ch06.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import kr.spring.ch06.vo.MemberVO;
public class MemberValidator implements Validator{
// Valdator가 검증할 수 있는 타입인지를 검사
@Override
public boolean supports(Class<?> clazz) {
// 유효성 검사를 진행하는 객체가 java bean의 형태인지 확인
return MemberVO.class.isAssignableFrom(clazz);
}
// 유효성 체크를 실질적으로 수행하는 메서드
// target : 검증하는 자바빈(VO) 객체
// errors : 예외의 정보를 담는 객체
@Override
public void validate(Object target, Errors errors) {
MemberVO vo = (MemberVO)target;
if(vo.getId() == null || vo.getId().trim().isEmpty()) {
errors.rejectValue("id", "required");
// 필드 에러코드 에러 문구
//errors.rejectValue("id", null, "ID는 필수 항목입니다.");
}
if(vo.getName() == null || vo.getName().trim().isEmpty()) {
errors.rejectValue("name", "required");
//errors.rejectValue("name", null, "이름은 필수 항목입니다.");
}
if(vo.getZipcode() == null || vo.getZipcode().trim().isEmpty()) {
errors.rejectValue("zipcode", "required");
//errors.rejectValue("zipcode", null, "우편번호는 필수 항목입니다.");
}
if(vo.getAddress1() == null || vo.getAddress1().trim().isEmpty()) {
errors.rejectValue("address1", "required");
//errors.rejectValue("address1", null, "주소는 필수 항목입니다.");
}
if(vo.getAddress2() == null || vo.getAddress2().trim().isEmpty()) {
errors.rejectValue("address2", "required");
//errors.rejectValue("address2", null, "상세 주소는 필수 항목입니다.");
}
}
}

package kr.spring.ch07.vo;
public class LoginVO {
private String userId;
private String password;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "LoginVO [userId=" + userId + ", password=" + password + "]";
}
}
package kr.spring.ch07.controller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import kr.spring.ch07.validator.LoginValidator;
import kr.spring.ch07.vo.LoginVO;
@Controller
public class LoginController {
// 유효성 체크를 위한 자바빈 초기화
@ModelAttribute
public LoginVO initCommand() {
return new LoginVO();
}
// 폼 호출하기
@GetMapping("/login/login.do")
public String form() {
return "login/form";
}
@PostMapping("/login/login.do")
public String submit(@ModelAttribute LoginVO vo, BindingResult result) {
System.out.println(vo);
new LoginValidator().validate(vo, result);
if(result.hasErrors()) {
return "login/form";
}
return "login/login";
}
}
package kr.spring.ch07.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import kr.spring.ch07.vo.LoginVO;
public class LoginValidator implements Validator{
@Override
public boolean supports(Class<?> clazz) {
return LoginVO.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
LoginVO vo = (LoginVO)target;
if(vo.getUserId() == null || vo.getUserId().trim().isEmpty()) {
errors.rejectValue("userId", "loginerror");
}
if(vo.getPassword() == null || vo.getPassword().trim().isEmpty()) {
errors.rejectValue("password", "loginerror");
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<form:form action="login.do" modelAttribute="loginVO">
아이디 : <form:input path="userId"/> <form:errors path="userId"/>
<br>
비밀번호 : <form:password path="password"/> <form:errors path="password"/>
<br>
<form:button>로그인</form:button>
</form:form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
로그인이 완료되었습니다. <br>
현재 로그인 된 아이디는 ${loginVO.userId}, 비밀번호는 ${loginVO.password } 입니다.
</body>
</html>

# rejectValue()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드. 커맨드 객체 이름 . 필드명 required.loginVO.userId
#2) 에러코드. 필드명 required.userId
#3) 에러코드. 필드타입 required.java.lang.String
#4) 에러코드 required
# 에러 코드 = 에러 문구
required = 필수 항목입니다.
required.userId = 사용자 아이디는 필수 항목입니다.
required.password= 비밀번호는 필수 항목입니다.

package kr.spring.ch07.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import kr.spring.ch07.service.LoginCheckException;
import kr.spring.ch07.service.LoginService;
import kr.spring.ch07.validator.LoginValidator;
import kr.spring.ch07.vo.LoginVO;
@Controller
public class LoginController {
@Autowired
private LoginService loginService;
// 유효성 체크를 위한 자바빈 초기화
@ModelAttribute
public LoginVO initCommand() {
return new LoginVO();
}
// 폼 호출하기
@GetMapping("/login/login.do")
public String form() {
return "login/form";
}
@PostMapping("/login/login.do")
public String submit(@ModelAttribute LoginVO loginVO, BindingResult result) {
System.out.println(loginVO);
new LoginValidator().validate(loginVO, result);
if(result.hasErrors()) {
return "login/form";
}
// 로그인 체크
try {
loginService.checkLogin(loginVO);
// 로그인 성공
return "redirect:/index.jsp";
} catch (LoginCheckException e) {
// 로그인 실패
// 메세지 처리하기 에러코드
result.reject("invalidIdOrPassword");
return form();
}
}
}
package kr.spring.ch07.service;
import kr.spring.ch07.vo.LoginVO;
public class LoginService {
public void checkLogin(LoginVO vo) throws LoginCheckException{
// 테스트용으로 userId와 password가 일치하면 로그인 처리
if(!vo.getUserId().equals(vo.getPassword())) {
System.out.println("인증 에러 - " + vo.getUserId());
throw new LoginCheckException();
}
}
}
package kr.spring.ch07.service;
public class LoginCheckException extends Exception{
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<form:form action="login.do" modelAttribute="loginVO">
<!-- 필드가 없는 에러메시지를 처리하기 위해서 명시 -->
<form:errors element="div" cssStyle="margin-bottom:10px; color:red; font-weight:bold;"/>
아이디 : <form:input path="userId"/> <form:errors path="userId" cssStyle="color:red;"/>
<br>
비밀번호 : <form:password path="password"/> <form:errors path="password" cssStyle="color:red;"/>
<br>
<form:button>로그인</form:button>
</form:form>
</body>
</html>
# rejectValue()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드. 커맨드 객체 이름 . 필드명 required.loginVO.userId
#2) 에러코드. 필드명 required.userId
#3) 에러코드. 필드타입 required.java.lang.String
#4) 에러코드 required
# reject()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드 . 커맨드 객체 이름
#2) 에러코드
# 에러 코드 = 에러 문구
required = 필수 항목입니다.
required.userId = 사용자 아이디는 필수 항목입니다.
required.password= 비밀번호는 필수 항목입니다.
invalidIdOrPassword = 아이디 또는 비밀번호가 불일치합니다!

라이브러리에 추가하기

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
package kr.spring.ch08.vo;
import org.springframework.web.multipart.MultipartFile;
public class SubmitReportVO {
private String subject;
private MultipartFile reportFile;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public MultipartFile getReportFile() {
return reportFile;
}
public void setReportFile(MultipartFile reportFile) {
this.reportFile = reportFile;
}
@Override
public String toString() {
return "SubmitReportVO [subject=" + subject + ", reportFile=" + reportFile + "]";
}
}
package kr.spring.ch08.controller;
import java.io.File;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import kr.spring.ch08.validator.SubmitReportValidator;
import kr.spring.ch08.vo.SubmitReportVO;
@Controller
public class SubmitReportController {
//파일 업로드
@Value("${file_path}")
private String path;
// 유효성 체크를 위한 자바빈 초기화
@ModelAttribute("report")
public SubmitReportVO initCommand() {
return new SubmitReportVO();
}
// 폼 호출하기
@GetMapping("/report/submitReport.do")
public String form() {
return "report/submitReportForm";
}
// 폼 등록하기
@PostMapping("/report/submitReport.do")
public String submit(@ModelAttribute("report") SubmitReportVO submitReportVO, BindingResult result) throws IllegalStateException, IOException {
// 전송된 데이터 유효성 체크하기
new SubmitReportValidator().validate(submitReportVO, result);
// 유효성 체크 결과 오류가 있으면 폼을 호출
if(result.hasErrors()) {
return form();
}
// 정상적으로 파일 업로드에 성공하였을 경우
File file = new File(path + "/" + submitReportVO.getReportFile().getOriginalFilename());
// 지정한 경로에 파일을 저장하기
submitReportVO.getReportFile().transferTo(file);
System.out.println(submitReportVO);
return "report/submittedReport";
}
}
file_path = C:/Users/user/git/Spring/ch08SpringMVC/src/main/webapp/upload
<!-- multipartResolver -->
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/><!-- 50M -->
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<!-- 파일 업로드 경로가 명시된 설정 파일 지정 -->
<context:property-placeholder location="classpath:config/file.properties"/>
<!-- 파일 업로드 -->
<beans:bean class="kr.spring.ch08.controller.SubmitReportController"/>
package kr.spring.ch08.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import kr.spring.ch08.vo.SubmitReportVO;
public class SubmitReportValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return SubmitReportVO.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
SubmitReportVO vo = (SubmitReportVO)target;
if(vo.getSubject() == null || vo.getSubject().trim().isEmpty()) {
errors.rejectValue("subject", "required");
}
if(vo.getReportFile() == null || vo.getReportFile().isEmpty()) {
errors.rejectValue("reportFile", "required");
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>리포트 등록 폼</title>
</head>
<body>
<form:form action="submitReport.do" enctype="multipart/form-data" modelAttribute="report">
<ul>
<li>
<form:label path="subject">제목</form:label>
<form:input path="subject" cssStyle="margin-bottom:10px;"/>
<form:errors path="subject" cssStyle="color:red; font-weight:bold;"/>
</li>
<li>
<form:label path="reportFile">파일</form:label>
<input type="file" id="reportFile" name="reportFile"/>
<form:errors path="reportFile" cssStyle="color:red; font-weight:bold;"/>
</li>
</ul>
<form:button>신고</form:button>
</form:form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>리포트 등록 완료</title>
</head>
<body>
<b>신고가 완료되었습니다.</b><br>
제목 : ${report.subject } <br>
파일 : ${report.reportFile.originalFilename }<br>
용량 : ${report.reportFile.size }
</body>
</html>
