스프링5 프로그래밍입문 12장

4900 단어 SpringSpring

MVC2

메시지

스프링에서 기본적인 문자열이나 메세지를 출력할때 JSP에 하드 코딩하여 나타낸다.
그런대 중복 사용되는 직접 하드 코딩하면 동일 문자영을 변경할 때 문제가 있다.
하드 코딩된 모든 코드를 찾아서 변경 해야되기 때문이다.
(인텔리j로 코딩하면 그냥 다 찾아서 바꾸는게 어렵진 않다.)
src/main/resources에 message 폴더를 생성하고 폴더에 label.properties 파일을 생성한다.

	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource ms = 
				new ResourceBundleMessageSource();
		ms.setBasenames("message.label");
		ms.setDefaultEncoding("UTF-8");
		return ms;
	}

스프링 설정에 추가해 준다.
프로퍼티 값으로 message.label을 주었고 이는 message패키지에 속한 label 프로퍼티 파일로부터 메시지를 읽어온다고 설정한 것이다.
빈의 아이디를 꼭 messageSource()로 생성해야 한다.
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
를 jsp상단에 입력 해주고 <spring:message code="email" />이러한 형태로 메세지를 출력할 수 있다.
국가 별로 메세지를 따로 지정할 수도 있다.
labelko.properties
label_en.properties
label
뒤에 언어형식의 접미시가 붙고 ko는 한국어, en은 영어로 사용하면 된다.

커맨드 객체 검증과 에러 코드 지정

public interface Validator {
	boolean supports(Class<?> clazz);
	void validate(@Nullable Object target, Errors errors);

}

스프링에서 지원하는 검증 객체의 인터페이스 이다.
supports는 boolean타입으로 검증이 가능한지 불가능한지를 알려준다.
target는 검증할 데이터를 넣어 주면 되고 errors는 오류 결과를 담으면 된다.

//컨트롤러 클래스
@Controller
public class RegisterController {

	private MemberRegisterService memberRegisterService;

	public void setMemberRegisterService(
			MemberRegisterService memberRegisterService) {
		this.memberRegisterService = memberRegisterService;
	}

	@RequestMapping("/register/step1")
	public String handleStep1() {
		return "register/step1";
	}

	@PostMapping("/register/step2")
	public String handleStep2(
			@RequestParam(value = "agree", defaultValue = "false") Boolean agree,
			Model model) {
		if (!agree) {
			return "register/step1";
		}
		model.addAttribute("registerRequest", new RegisterRequest());
		return "register/step2";
	}

	@GetMapping("/register/step2")
	public String handleStep2Get() {
		return "redirect:/register/step1";
	}

	@PostMapping("/register/step3")
	public String handleStep3(RegisterRequest regReq, Errors errors) {
		new RegisterRequestValidator().validate(regReq, errors);
		if (errors.hasErrors())
			return "register/step2";

		try {
			memberRegisterService.regist(regReq);
			return "register/step3";
		} catch (DuplicateMemberException ex) {
			errors.rejectValue("email", "duplicate");
			return "register/step2";
		}
	}

}
//검증 클래스
public class RegisterRequestValidator implements Validator {
	private static final String emailRegExp = 
			"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" +
			"[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
	private Pattern pattern;

	public RegisterRequestValidator() {
		pattern = Pattern.compile(emailRegExp);
		System.out.println("RegisterRequestValidator#new(): " + this);
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return RegisterRequest.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		System.out.println("RegisterRequestValidator#validate(): " + this);
		RegisterRequest regReq = (RegisterRequest) target;
		if (regReq.getEmail() == null || regReq.getEmail().trim().isEmpty()) {
			errors.rejectValue("email", "required");
		} else {
			Matcher matcher = pattern.matcher(regReq.getEmail());
			if (!matcher.matches()) {
				errors.rejectValue("email", "bad");
			}
		}
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required");
		ValidationUtils.rejectIfEmpty(errors, "password", "required");
		ValidationUtils.rejectIfEmpty(errors, "confirmPassword", "required");
		if (!regReq.getPassword().isEmpty()) {
			if (!regReq.isPasswordEqualToConfirmPassword()) {
				errors.rejectValue("confirmPassword", "nomatch");
			}
		}
	}

}

컨트롤러 클래스에서 supports()메소드는 파라미터로 전달받은 clazz 객체가 RegisterRequest클래스로 타입 변환이 가능한지 확인한다.
rejectIfEmptyOrWhitespace - 공백이거나 null이거나 빈문자열일 경우
rejectIfEmpty - 공백이거나 null 일경우
errors.hasErrors() 메소드를 이용해서 에러가 존재하는지 검사한다.
검증 범위를 지정할 수있으며 글로벌 객체의 경우 애노테이션을 사용할 수 있는대 버전에 따라 다르다.
커맨드에 프로퍼티에 애노태이션을 작성하면 되는대

버전 마다 다르니 사용하고자 하는 애노테이션을 버전에 따라 검색하여 사용하면 좋을거같다.

좋은 웹페이지 즐겨찾기