먼저 Controller에서 수행되는 로직을 분석한다.
[RegistMemberController.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | package login.controller; @Controller @RequestMapping("/member/regist") public class RegistMemberController { private String formViewName = "registMemberForm"; @RequestMapping(method = RequestMethod.GET) public String form(Model model) { referenceData(model); //Model 객체를 선언한 변수 model을 들고 메서드실행 //referenceData 메서드내에서 //Model 생성자 오버로딩해서 add를 수행하고 돌아온다. //위에 Model 컨트롤 우클릭하면 확인 가능. return formViewName; } private void referenceData(Model model) { List<Code> jobCodes = new ArrayList<Code>(); jobCodes.add(new Code("1", "개발자")); jobCodes.add(new Code("2", "UI 개발자")); jobCodes.add(new Code("3", "웹 디자이너")); jobCodes.add(new Code("4", "기획자")); String[] favoritesOsNames = {"윈도우XP" , "비스타", "윈도우7" , "우분투", "맥"}; String [] tools = {"Eclipse","IntelliJ","NetBeans"}; model.addAttribute("jobCodes", jobCodes); model.addAttribute("favoritesOsNames", favoritesOsNames); model.addAttribute("tools", tools); } //이름지정하지않았으므로 return한 DTO객체 첫글자 소문자로 이름이 지정("memberInfo") @ModelAttribute protected Object formBackingObject() throws Exception{ return new MemberInfo(); /* - 이 메서드를 선언한 이유 - 1. 밑에 @ModelAttribute로도 객체생성했지만 위에 GET방식으로 요청이 들어올때에는 밑에 객체의 정보가 없음을 인지해야합니다 즉, Command 객체의 정보가 필요합니다 2. 필요한 이유는 GET방식으로 들어왔을때에 Command객체를 모델데이터로 올려놔야 registMemberForm.jsp에서 <form:form commandName =""> 여기에 정보를 담을 수 있습니다. */ } @RequestMapping(method = RequestMethod.POST) public String submit(@ModelAttribute MemberInfo memberInfo, BindingResult result, Model model) { new MemberInfoValidator().validate(memberInfo, result); checkDuplicateId(memberInfo.getUserId(), result); if(result.hasErrors()) { referenceData(model); return formViewName; } return "registMember"; /* 여기서의 @ModelAttribute MemberInfo 를 함부로 다른 이름으로 지정하면 안됩니다. 1. 위에 @ModelAttribute("") 의 이름을 따로 지정하지 않았습니다. 2. 이 메서드에는 Validator를 통한 errors 태그를 사용하기위한 데이터를 보낼 메서드가 있기때문에 에러가 났을때 다시 이 jsp뷰를 뿌려줄때(돌아와야할때) <form:form commandName =""을 다시실행하는데 커맨드 객체의 이름이 달라지면 에러가 안불려와집니다. 다른 이름으로 지정하고싶다면 위의 MemberInfo도 같이 맞춰줍시다. */ } private void checkDuplicateId(String userId, BindingResult errors) { if(userId.equals("madvirus")) { errors.rejectValue("userId", "duplicate"); } } } | cs |
나머지는 그전에 했던 예제들과 비슷하기때문에 생략.
[registMemberForm.jsp]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <form:form commandName="memberInfo"> <p> <form:label path="userId">회원 ID</form:label> <form:input path="userId" /> <form:errors path="userId" /> </p> <p> <form:label path="name">이름</form:label> <form:input path="name" /> <form:errors path="name" /> </p> <p> <form:label path="address.address1">주소1</form:label> <form:input path="address.address1" /> <form:errors path="address.address1" /> </p> <p> <form:label path="address.address2">주소2</form:label> <form:input path="address.address2" /> <form:errors path="address.address2" /> </p> <p> <form:label path="jobCode">직업</form:label> <form:select path="jobCode" > <option value="">--- 선택하세요 ---</option> <form:options items="${jobCodes}" itemLabel="label" itemValue="code" /> <!-- jobCodes는 --> </form:select> <form:errors path="jobCode" /> </p> <p> <form:label path="favorites">선호 OS</form:label> <form:checkboxes items="${favoritesOsNames}" path="favorites" /> <%-- <form:checkbox path="favorites" value="윈도우XP" label="윈도우XP" /> <form:checkbox path="favorites" value="비스타" label="비스타" /> <form:checkbox path="favorites" value="윈도우7" label="윈도우7" /> <form:checkbox path="favorites" value="우분투" label="우분투" /> <form:checkbox path="favorites" value="맥" label="맥" /> --%> <form:errors path="favorites" /> </p> <p> <form:label path="tool">주로 사용하는 개발툴</form:label> <form:radiobuttons items="${tools}" path="tool" /> </p> <p> <form:label path="etc">기타</form:label> <form:textarea path="etc" cols="20" rows="3"/> </p> <p> <form:checkbox path="contractAgreement" label="약관에 동의합니다."/> </p> <p> <input type="submit" value="회원 등록"> </p> </form:form> | cs |
처음 <form:form commandName ="memberInfo"> 로 받아온 부분을 확인할 수 있다.
- 커맨드 객체의 정보를 가져오는 방법 두가지 -
1. commandName으로 "memberInfo"라고 설정되어있으면 @ModelAttribute("memberInfo") 형식으로 지정되어있거나
이름을 설정하지않아도 클래스명이 MemberInfo.java 클래스기때문에 자동으로 첫글자 소문자로 memberInfo로 저장!
2. commandName의 속성값을 따로 지정하지 않으면 "command"라는 이름으로 찾아간다.
둘다 없으면 에러처리나서 jsp페이지 실행 X
- itemLabel / itemValue
Command객체(DTO)에서 String으로 가져오면 값이 하나로 뽑으면 되지만
하나의 태그에 각각 달리 값을 먹이고 싶다면 다음과 같은 방법도 가능하다.
1 2 3 4 5 6 7 | List<Code> jobCodes = new ArrayList<Code>(); jobCodes.add(new Code("1", "개발자")); jobCodes.add(new Code("2", "UI 개발자")); jobCodes.add(new Code("3", "웹 디자이너")); jobCodes.add(new Code("4", "기획자")); model.addAttribute("jobCodes", jobCodes); | cs |
1. 생성자 오버로딩을 통한 DTO객체
2. 를 저장한 List
3. 를 model데이터에 추가
세단계로 나누어서
1 | <form:options items="${jobCodes}" itemLabel="label" itemValue="code" /> | cs |
클라이언트에게 보여질 페이지에 내용으로 itemLabel 값을
value속성으로 넣을 데이터를 itemValue로 변수명으로 선언해주면 가능 !
items는 컬렉션만 들어올수있으니 List로 넣을 수 있고
그것을 <options> 태그가 list에 있는것을 하나씩 꺼낼때마다 순서대로 꺼낸다.
꺼낼때에는 EL이아니라 커맨드 객체에 선언된 변수명으로 꺼낼 수 있음을 기억하자.
[Code.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package login.controller; public class Code { private String code; private String label; public Code() {} public Code(String code, String label) { super(); this.code = code; this.label = label; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } } | cs |
'JAVA > Spring' 카테고리의 다른 글
Spring MVC - 파일다운로드(view,model설정법) (0) | 2018.09.20 |
---|---|
Spring MVC - Tiles로 jsp구성하기 (1) | 2018.09.20 |
Spring이 제공하는 폼 관련 커스텀 태그(밑에 글과 연동) (5) | 2018.09.19 |
Spring MVC - 두번째 LoginController (0) | 2018.09.19 |
String MVC - 뷰(ViewResolver) 원칙 (0) | 2018.09.19 |