교재 실습/자바 웹 개발 워크북

86. 리플랙션 API를 이용하여 프런트 컨트롤러 개선하기 (2)

Jint 2022. 8. 4. 21:57

3. 페이지 컨트롤러의 DataBinding 구현

클라이언트가 보낸 데이터를 사용하는 페이지 컨트롤러는 MemberAddController, MemberUpdateController, MemberDeleteController, LogInController 이다. 이들 중에서 먼저 MemberAddController 클래스에 대해 DataBinding 인터페이스를 적용해본다.

spms.controls.MemberAddController 클래스를 다음과 같이 편집한다.

package spms.controls;

import java.util.Map;

import spms.bind.DataBinding;
import spms.dao.MySqlMemberDao;
import spms.vo.Member;

//의존 객체 주입을 위해 인스턴스 변수와 셋터 메서드 추가, 의존 객체를 꺼내는 기존 코드 변경(주석처리)
public class MemberAddController implements Controller, DataBinding {//Map 객체에 저장할 파라미터에 대한 정보 제공 - DataBinding 인터페이스 구현
	MySqlMemberDao memberDao; //인스턴스 변수
	
	//셋터 메서드
	public MemberAddController setMemberDao(MySqlMemberDao memberDao) {
		this.memberDao = memberDao;
		return this; //셋터 메서드 쉽게 사용하기 위해 자신의 인스턴스 값 반환
	}
	
	//DataBinding 인터페이스의 구현 메서드
	public Object[] getDataBinders() {
		//클라이언트가 보낸 매개변수를 Member 인스턴스에 담아 "member"라는 이름으로 Map객체에 저장해라
		return new Object[] {"member", spms.vo.Member.class};
	}
	
	//Controller 인터페이스의 구현 메서드
	@Override
	public String execute(Map<String, Object> model) throws Exception {
		/*if(model.get("member") == null) {//입력폼을 요청할 때 - GET
			return "/member/MemberForm.jsp";
		}else {//회원 등록 요청할 때 - POST
			//MemberDao memberDao = (MemberDao)model.get("memberDao");
			Member member = (Member)model.get("member");
			memberDao.insert(member);
			return "redirect:list.do";
		}*/
		//프런트 컨트롤러가 VO 객체를 무조건 생성할 것이기 때문에 Member 객체 여부로 판단하지 않는다.
		Member member = (Member)model.get("member");
		if(member.getEmail() == null) {//입력폼을 요청할 때
			return "/member/MemberForm.jsp";
		}else {//회원 등록을 요청할 때
			memberDao.insert(member);
			return "redirect:list.do";
	    }
	}
}

 

- DataBinding 인터페이스 선언

MemberAddController 클래스는 클라이언트가 보낸 데이터를 프런트 컨트롤러로부터 받아야 하기 때문에, 위에서 정의한 규칙에 따라 DataBinding 인터페이스를 구현한다.

public class MemberAddController implements Controller, DataBinding {//Map 객체에 저장할 파라미터에 대한 정보 제공 - DataBinding 인터페이스 구현
    ...
}

 

- getDataBinders() 메서드 구현

DataBinding 인터페이스를 구현한다고 선언했으니 이 인터페이스에 정의된 getDataBinders() 메서드를 구현해야 한다. MemberAddController 클래스가 원하는 데이터는 사용자가 회원 등록폼에 입력한 회원 이름과 이메일, 암호값이다. 이 메서드의 반환값, Object 배열을 살펴본다. 그 의미는 클라이언트가 보낸 매개변수 값을 Member 인스턴스에 담아서 "member"라는 이름으로 Map 객체에 저장해 달라는 뜻이다.

//DataBinding 인터페이스의 구현 메서드
public Object[] getDataBinders() {
    //클라이언트가 보낸 매개변수를 Member 인스턴스에 담아 "member"라는 이름으로 Map객체에 저장해라
    return new Object[] {"member", spms.vo.Member.class};
}

프런트 컨트롤러는 Object 배열에 지정된 대로 Member 인스턴스를 준비하여 Map 객체에 저장하고, execute() 메서드를 호출할 때 매개변수로 이 Map 객체를 넘길 것이다.

 

- execute() 메서드

기존의 execute() 메서드에 비교해 조건문이 약간 달라졌다. 이전 코드에서는 Map 객체에 Member 객체가 들어 있는지 없는지에 따라 작업을 분기하였다.

//execute() 메서드의 이전 코드
if(model.get("member") == null) {//입력폼을 요청할 때 - GET
    return "/member/MemberForm.jsp";
}else {//회원 등록 요청할 때 - POST
    //MemberDao memberDao = (MemberDao)model.get("memberDao");
    Member member = (Member)model.get("member");
    memberDao.insert(member);
    return "redirect:list.do";
}

하지만, 이제부터는 getDataBinders() 메서드에서 지정한 대로 프런트 컨트롤러가 VO 객체를 무조건 생성할 것이기 때문에 Member 객체가 있는지 여부로 판단해서는 안 된다. 대신 다음과 같이 Member 객체에 이메일이 들어 있는지 여부로 검사해야 한다.

//execute() 메서드의 현재 코드
Member member = (Member)model.get("member");
if(member.getEmail() == null) {//입력폼을 요청할 때
    return "/member/MemberForm.jsp";
}else {//회원 등록을 요청할 때
    memberDao.insert(member);
    return "redirect:list.do";
}

 

클라이언트에서 데이터를 보내지 않는 MemberListController와 LogOutController를 빼고 나머지 모든 페이지 컨트롤러에 대해서도 DataBinding 인터페이스를 구현한다.

 

- MemberUpdateController 구현 힌트

MemberUpdateController 클래스는 변경폼을 출력할 때 회원 번호가 필요하고, 데이터를 변경할 때 Member 인스턴스가 필요하기 때문에 다음과 같이 Object 배열을 반환해야 한다.

return new Object[] {"no", Integer.class, "member", spms.vo.Member.class};

프런트 컨트롤러는 MemberUpdateController 클래스를 실행할 때 no나 Member 객체 관련 매개변수를 찾아서 Map 객체에 데이터를 준비할 것이다.

 

- MemberDeleteController 구현 힌트

MemberDeleteController 클래스는 회원 정보를 삭제할 때 회원 번호가 필요하다. 다음은 getDataBinders() 메서드가 반환해야 할 Object 배열이다.

return new Object[] {"no", Integer.class};

 

- LogInController 구현 힌트

LogInController 클래스는 사용자가 입력한 이메일과 암호가 필요하다.

return new Object[] {"loginInfo", spms.vo.Member.class};

 

참고도서 : https://freelec.co.kr/book/1674/

 

[열혈강의] 자바 웹 개발 워크북

[열혈강의] 자바 웹 개발 워크북

freelec.co.kr