TIL 0618

먼지·2024년 6월 18일

Today I Learned

목록 보기
79/89
post-thumbnail

이론

주요 폼 관련 커스텀 태그

주요 폼 태그

커스텀 태그설명
<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> 태그를 위한 커스텀 태그

CSS와 관련된 공통 속성

속성설명
cssClassHTML의 class 속성값
cssErrorClass폼 검증 에러가 발생했을 때 사용할 HTML의 class 속성값
cssStyleHTML의 style 속성값

Validator 인터페이스를 이용한 폼 값 검증

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");
		}

	}
}

메시지 처리

MessageSource를 이용한 메시지 국제화 처리

국제화 지원을 위해 org.springframework.context.MessageSource 인터페이스를 제공

	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
   	 <property name="basenames">
   	            <value>message.greeting</value>
   	 </property>
    </bean>
  • ResourceBundle은 프로퍼티 파일의 이름을 이용해 언어 및 지역에 따른 메시지 로딩
    message.properties : 기본 메시지
    message_ko.properties : 한글 메시지
    message_en_US.properties : 미국을 위한 영어 메시지

에러 코드 호출시 메서드 사용

  • reject() 메서드를 이용하여 커맨드 객체 자체에 대한 에러 코드를 입력한 경우, 다음의 순서로 메시지 코드를 생성
    1) 에러코드 + “.” + 커맨드 객체 이름
    2) 에러코드

  • rejectValue() 메서드를 이용하여 특정 필드에 대한 에러 코드를 입력했다면, 다음의 순서로 메시지 코드를 생성
    1)에러코드 + “.” + 커맨드 객체 이름 + “.” + 필드명
    2)에러코드 + “.” + 필드명
    3)에러코드 + “.” + 필드 타입
    4)에러코드

  • 예시
    1) required.loginCommand.userId
    2) required.userId
    3) required.java.lang.String
    4) required

파일 업로드 처리

Multipart Resolver 설정

<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 클래스의 프로퍼티

프로퍼티타입설명
maxUploadSizelong최대 업로드 가능한 바이트 크기, -1은 제한이 없음을 의미한다. 기본값은 -1이다.
maxInMemorySizeint디스크에 임시 파일을 생성하기 전에 메모리에 보관할 수 있는 최대 바이트 크기. 기본값은 10240 바이트이다.
defaultEncodingString요청을 파싱할 때 사용할 캐릭터 인코딩. 지정하지 않을 경우, 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();
}

실습

kr.spring.ch05.controller

Game Search Controller

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";
	}
}

Servlet Context XML

<beans:bean class="kr.spring.ch05.controller.GameSearchController"/>

Main.jsp

<%@ 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>

kr.spring.ch05.vo

Search VO

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 + "]";
	}
}

kr.spring.ch05.service

Search Service

package kr.spring.ch05.service;

import kr.spring.ch05.vo.SearchVO;

public class SearchService {
	public String search(SearchVO vo) {
		System.out.println(vo);
		
		return "검색 완료!";
	}
}

kr.spring.ch05.controller

Game Search Controller

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;
	}
}

Servlet Context XML

<!-- 파라미터로 전달된 데이터를 자바빈에 담기 -->
	<beans:bean class="kr.spring.ch05.controller.GameSearchController"/>
	<beans:bean class="kr.spring.ch05.service.SearchService"/>

Game.jsp

<%@ 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>

kr.spring.ch06.controller

혼자 작성해본 코드

Create Account Controller

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;
	}
	
}

kr.spring.ch06.vo

Account VO

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 + "]";
	}
	
}

kr.spring.ch06.service

Account Service

package kr.spring.ch06.service;

import kr.spring.ch06.vo.AccountVO;

public class AccountService {
	public String create(AccountVO vo) {
		System.out.println(vo);
		
		return "회원가입이 완료되었습니다!";
	}
}

Created.jsp

<%@ 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>


강사님 코드

Create Account Controller

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";
	}
	
}

Created.jsp

<%@ 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>


유효성 체크하기

kr.spring.ch06.validator

Member Validator

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, "상세 주소는 필수 항목입니다.");
		}
	}
	
}

Creation Form

<%@ 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>

Create Account Controller

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";
	}
	
}

Created.jsp

<%@ 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>

validation.properties

# 에러 코드 = 에러 문구
required = 필수 항목입니다.

Servlet - Context XML

<!-- 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>
	

Member Validation

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, "상세 주소는 필수 항목입니다.");
		}
	}
	
}


kr.spring.ch07.vo

LoginVO

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 + "]";
	}
}

kr.spring.ch07.controller

Login Controller

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";
	}

}

kr.spring.ch07.validator

Login Validator

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");
		}
		
	}

}

View - Login

Form.jsp

<%@ 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>

Login.jsp

<%@ 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>


Validation Properties

# rejectValue()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드. 커맨드 객체 이름 . 필드명 required.loginVO.userId
#2) 에러코드. 필드명  required.userId
#3) 에러코드. 필드타입 required.java.lang.String
#4) 에러코드 required


# 에러 코드 = 에러 문구
required = 필수 항목입니다.
required.userId = 사용자 아이디는 필수 항목입니다.
required.password= 비밀번호는 필수 항목입니다.


Login Controller

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();
		}  
		
	}

}

kr.spring.ch07.service

Login Service

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();
		}
	}
}

Login Check Exception

package kr.spring.ch07.service;

public class LoginCheckException extends Exception{
	
}

View - Login

Form.jsp

<%@ 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>

Validation Properties

# rejectValue()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드. 커맨드 객체 이름 . 필드명 required.loginVO.userId
#2) 에러코드. 필드명  required.userId
#3) 에러코드. 필드타입 required.java.lang.String
#4) 에러코드 required

# reject()를 사용할 경우 다음의 순서로 메시지 코드 생성
#1) 에러코드 . 커맨드 객체 이름
#2) 에러코드

# 에러 코드 = 에러 문구
required = 필수 항목입니다.
required.userId = 사용자 아이디는 필수 항목입니다.
required.password= 비밀번호는 필수 항목입니다.
invalidIdOrPassword = 아이디 또는 비밀번호가 불일치합니다!


Pom.XML

라이브러리에 추가하기

<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.2</version> 
</dependency>

kr.spring.ch08.vo

Submit Report VO

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 + "]";
	}
	
}

kr.spring.ch08.controller

Submit Report Controller

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";
	}
	
}

config - file.properties

file_path = C:/Users/user/git/Spring/ch08SpringMVC/src/main/webapp/upload

Servlet - Context XML

<!-- 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"/>
	

kr.spring.ch08.validator

Submit Report Validator

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");
		}
		
	}

}

Views - report

Submit Report Form

<%@ 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>

Submitted Report

<%@ 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>
profile
Lucky Things🍀

0개의 댓글