본문 바로가기
JAVA/Spring

Spring MVC - itemLabel, itemValue 예제.

by 설총이 2018. 9. 19.




먼저 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