Form
command 객체를 이용한 Form 처리
command를 이용하지 않을 때 controller는 전달되는 값을 다음과 같이 처리한다.
@Controller
@RequestMapping("/article/newArticle.do")
public class NewArticleController {
...
@RequestMapping(method=RequestMethod.POST)
public String submit(@RequestParam(“parentId”) int pid,
@RequestParam(“title”) String title,
@RequestParam(“content”) String content) {
NewArticleCommand article = new NewArticleCommand();
article.setParentId(pid);
article.setTitle(title); article.setContent(content);
... // 입력 값 처리
return "article/newArticleSubmitted"; // 결과 view
}
}
요청 parameter들을 각각 추출해서 전달해야함.
form의 각 항목들과 property이름이 일치하는 command class를 다음과 같이 만든다.
public class NewArticleCommand {
private int parentId;
private String title;
private String content;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
... // getter & setter methods
}
이를 이용하면 다음과 같이 NewArticleCommand 클래스 타입의 파라미터를 지정해 객체를 전달 할 수 있다,
@Controller
@RequestMapping("/article/newArticle.do")
public class NewArticleController {
...
@RequestMapping(method=RequestMethod.POST)
public String submit(NewArticleCommand article) {
DispatcherServlet은 command 객체를 생성하고 form 입력값들에 대응되는 property에 저장한 후 리퀘스트 핸들러 메소드에 전달한다. 자동 타입 변환이 이루어진다.
view 에서 command 객체에 접근할 때에는
<html>
<head><title>게시글 쓰기</title></head>
<body>
게시글 등록됨:<br/>
제목: ${newArticleCommand.title} <br/>
내용: ${newArticleCommand.content}
</body>
</html>
command 클래스 이름과 동일하지만 첫글자가 소문자로 변환된 객체에서 변수들을 불러 올 수 있다.
@ModelAttribute 어노테이션을 사용하면 뷰에 전달될 command객체의 이름을 지정할 수 있다.
@RequestMapping(method=RequestMethod.POST)
public String submit(
@ModelAttribute(“article”) NewArticleCommand newArticle) {
이 경우 뷰에서는 article.title과 같이 불러올 수 있다.
Form 입력값 검증
Validator를 이용한 form 입력값을 검증을 위해서는 Validator interface를 구현해야한다.
핸들러 메소드에서 Errors 또는 BindingResult 타입의 인자를 정의 해야한다
(단, command 객체 인자 바로 뒤 인자로 정의 해야한다.)
Validator 객체를 생성한 뒤 validate()메소드를 호출한다. 이 때, Command 객체와 Errors 객체를 인자로 전달한다.
@Controller @RequestMapping("/account/create")
public class CreateAccountController {
@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") MemberInfo memberInfo,
Errors result ) { // Errors 타입 대신 BindingResult 타입도 가능
new MemberInfoValidator().validate(memberInfo, result); // 검증 실행
if (result.hasErrors())
return "account/creationForm"; // 검증 오류 발생 시 입력 form을 다시 출력
accountService.createAccount(memberInfo); // 오류가 없으면 service 호출
return "account/created"; // 결과 view 출력
} ...
}
@Valid 어노테이션을 이용하면 validate()메소드 호출이 불필요하다.
핸들로 메소드의 파라미터 중 검증이 필요한 객체 앞에 적용한다. 핸들러 메소드 실행 전에 먼저 실행된다.
오류 발생시 Errors나 BindingResult 타입 객체에 저장된다.
@Controller
@RequestMapping("/login/login.do")
public class LoginController {
…
@RequestMapping(method = RequestMethod.POST)
public String submit(@Valid LoginCommand loginCommand, BindingResult result) {
// new LoginCommandValidator().validate(loginCommand, result); 코드 불필요!
if (result.hasErrors()) return "login/form"; // 검증 오류 발생 시 login form으로 이동
…
}
@InitBinder // controller 범위 validator 설정을 위한 method
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new LoginCommandValidator());
}
}
@InitBinder는 특정 컨트롤러에서 사용할 validator를 설정한다.
WebDataBinder 객체를 파라미터로 전달 받는다.
setValidator() : 기존 global validator를 대체한 validator 지정
addValidator() : 기존 global validator를 유지하고 컨트롤러 범위 validator를 추가
@RequestMapping(method = RequestMethod.POST)
public String submit(@Valid LoginCommand loginCommand, BindingResult result) {
if (result.hasErrors()) return "login/form"; // 검증 오류 발생 시 login form으로 이동
…
}
@InitBinder // controller 범위 validator 설정을 위한 method
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new LoginCommandValidator());
}
Global Validaotr는 새로운 클래스를 정의하지 않고 범용적인 validaotor를 이용하여 검증한다.
command class 내에 @NotNull, @Size, @Digits 같은 annotation을 사용.
OptionalValidatorFactoryBean 객체를 등록해야하는데
<mvc:annotation-driven />또는 @EnableWebMvc 이용한다.
command 메소드 앞에 @Valid를 적용
Bean Validation API 1.1의 주요 어노테이션들
@Null @NotNull |
값이 null이면 안된다 ex) @Null String userName; |
@Min @Max @DecimalMin @DecimalMax |
값 제한 ex) @Min(5) int quanity; @DecimalMax("30.00") BigDecimal discount; |
@Size | String의 경우에는 길이를 Collection/Map/Array의 경우 사이즈를 제한한다 ex) @Size(min=2, max=50)String message; |
@Pattern | 정규식으로 내용을 검증함 ex) @Pattern(regexp= "\\(\\d{3}\\)\\d{3}-\\d{4}") String phoneNumber; |
@AssertTrue @AssertFalse |
true/false 값 지정 |
Bean Validation API 2.0의 주요 어노테이션들
@NotEmpty | CharSequence, Collection, Map, arrays에 null이거나 empty상태인지 확인 |
@NotBlank | 공백인지 확인한다 |
@Email(regexp=,flags=) | 이메일 검증 |
message/validation.properties에 메세지를 추가하면 오류메세지가 지정된다.
예를들어 MemberInfo클래스에 @Size(min=5, max=20) String id; 가 있을때 메세지파일에
Size.memberInfo.id=사용자 id는 {1}자 이상 {2}자 이내여야 합니다. 와 같이 지정하면 해당 오류가 출력된다.
따로 지정하지 않을 경우 validator provider가 제공하는 기본 메세지들이 출력된다.
@DateTimeFormat, @NumberFormat을 사용하여 타입 변환 설정이 가능하다.
@DateTimeFormat(pattern="yyyy/MM/dd") // “2015/04/20” → java.util.Date 타입 변환
private java.util.Date from;
@DateTimeFormat(iso=ISO.DATE_TIME) // “2015-04-21T13:30:55.113+08:30”
private java.util.Date to; //java.util.Date 타입 변환
@NumberFormat(patter="$###,##0.00") //"$1,234.56"
private java.math.BigDecimal amount;
'공부기록 > 스프링' 카테고리의 다른 글
스프링 view 구현 (jsp) (0) | 2023.05.23 |
---|---|
스프링 HTTP Session 사용 (0) | 2023.05.22 |
Spring MVC(1) - DispatcherServlet, Handler mapping, Controller (0) | 2023.04.25 |
스프링의 DI (0) | 2023.04.20 |
스프링 컨테이너와 스프링 빈 (0) | 2023.03.22 |