JAVA

3Tier: 예외처리,@Qualifier

docc 2021. 7. 27. 17:06

런타임예외가 아닌 경우에 예외별처리하기

 

	@Autowired
	I판매DAO 판매DAO;
	
	@Override
	public String 로그인가능여부확인하다(String id, String password) {
		HashMap<String, Object> 회원번호와성명 = null;
		try {
	         판매DAO.기록하다();
             A a1 = null;
             a1.g();
		} catch (Exception e) {
			//그럴 땐 이렇게 instanceof 로 예외의 종류를 확인해 걸면 된다.
			if(e instanceof ConnectException) {
				//...
			}
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "예외발생";
		}
		
		return "정상처리";
   }
런타임예외와 달리 ConnectException, SQLException 등은 그 메서드나 내용안에 직접적인
예외발생할 코드가 안보이면 예외를 걸 수가 없다. (위의 I판매DAO는 Interface 로 구현부가 없다.)
//문제점 : 예외별 처리를 위와 같이하면 자동 롤백이 안된다.(어느 예외에서 캐치되면 롤백이 안됨)
//해결책 : 수동롤백 (아래예시)
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
sql 같은 경우 jdbc 로 접근 하고 있는데 sql 서버가 중간에 종료되버리면 위의 Service 안에서의 try-catch 문은 들어가지 않아
예외가 캐치되지 않는다 (return 값인 "예외발생","정상처리" 도 나오지 않음)
사용하는 Controller 에서도 try-catch 사용해야하는 것이다. ( 그래야 잡힌다. )
그래서 아래의 Adapter 를 더 끼워서 예외를 처리한다.

Adapter

: Service 와 거의 유사하게 Interface 를 만들어 구현하고 Service 들을 호출해서 일을 시킨다.

일을 서로 계속 떠넘기는중 ( 작업 순서는 거꾸로 일 시키는 순서임 )

4. Controller(작업해서 가져온값 ModelAndView에 Model로 저장하여 View지정해 보내기)

-> 3. Adapter(일도하고,초기작업정도하고)

-> 2. Service

-> 1. Dataservice(DAO)

이런식으로 넘어가는 중이다.

adapter 참고사이트: https://niceman.tistory.com/141

​adapter 참고사이트2: https://yaboong.github.io/design-pattern/2018/10/15/adapter-pattern/

 

1. DAO ( 얘는 Mapper 를 가지고서 걔한테 일 시킴 )

public interface IMemberDAO {

	void save(Member member);

	HashMap<String,Object> isin(String id, String password);

	boolean isin(String id);

	void delete(int no);

	Member findByNo(int no);
	
	String findNameByNo(int no);

}

@Repository
public class MemberDAO implements IMemberDAO {
	
	@Autowired
	IMemberMapper memberMapper;
	
	@Transactional
	public void save(Member member) {
		memberMapper.save(member);
	}

	@Transactional
	public HashMap<String,Object> isin(String id, String password) {
		return memberMapper.isIn(id, password);
	}

	@Transactional
	public boolean isin(String id) {
		return !memberMapper.isIn2(id);
	}

	@Transactional
	public void delete(int no) {

	}

	@Transactional
	public Member findByNo(int no) {
		return memberMapper.findByNo(no);
	}
	
	@Transactional
	@Override
	public String findNameByNo(int no) {
		Member member = memberMapper.findByNo(no);
		return member.getName();
	}

}

1-1. Mapper

@Mapper
public interface IMemberMapper {

	@Select("select * from member;")
	List<Member> selectAll();
	
	@Select("select * from member where no=#{no}")
	Member findByNo(@Param("no") int 회원번호);

	@Insert("insert into member(name,post,address,detailaddress,tel,email,id,password,profile) values(#{name},#{post},#{address},#{detailaddress},#{tel},#{email},#{id},#{password},#{profile})")
	void save(Member member);
	
	@Select("select no,name from member where id=#{id} and password=#{password}")
	HashMap<String, Object> isIn(@Param("id")String id, @Param("password")String password);//no=1 , name=나길동 이렇게 HashMap 으로 컬럼명과 컬럼값이 들어간다.
	
	@Select("select if(count(*)=1,1,0) from member where id=#{id}")
	boolean isIn2(String id);//숫자가0 은 false로 반환, 0외의 모든 수는 true 임을 기억! DB에는 true false 가 없음
}

2. Service (manage패키지)

public interface I회원업무 {
	BusinessResult 회원등록준비하다();
	BusinessResult 회원등록하다(Member member);
	BusinessResult 회원을조회하다(int 회원번호);
	BusinessResult 회원프로필을조회하다(int 회원번호);
}

@Service("회원업무구현")
public class 회원업무 implements I회원업무 {
	@Autowired
	IMemberDAO memberDAO;
	
	@Override
	@Transactional
	public BusinessResult 회원등록준비하다() {
		return new BusinessResult();
	}

	@Override
	@Transactional
	public BusinessResult 회원등록하다(Member member) {
		return new BusinessResult();
	}

	@Override
	@Transactional
	public BusinessResult 회원을조회하다(int 회원번호) {
		return new BusinessResult();
	}

	@Override
	@Transactional
	public BusinessResult 회원프로필을조회하다(int 회원번호) {
		return new BusinessResult();
	}

}

3. Adapter (Service 와 거의 동일하게 똑같은 인터페이스를 구현하여 @Service 를 어노테이션으로)

@Service("회원업무")
public class 회원업무Adapter implements I회원업무{
	@Autowired @Qualifier("회원업무구현") I회원업무 회원업무구현;
	
	@Override
	public BusinessResult 회원등록준비하다() {
		BusinessResult br = null;
		try {
			br = 회원업무구현.회원등록준비하다();//얘도 BusinessResult return 이다.
			
		} catch (Exception e) {
			if(e instanceof TransactionSystemException) {
				return new BusinessResult(RESULTCODE.NETWORK_ERROR,"네트워크에 장애가 있습니다.");
			}
		}
		return br;
	}

	@Override
	public BusinessResult 회원등록하다(Member member) {
		BusinessResult br = null;
		try {
			br = 회원업무구현.회원등록하다(member);//얘도 BusinessResult return 이다.
			
		} catch (Exception e) {
			if(e instanceof TransactionSystemException) {
				return new BusinessResult(RESULTCODE.NETWORK_ERROR,"네트워크에 장애가 있습니다.");
			}
		}
		return br;
	}

	@Override
	public BusinessResult 회원을조회하다(int 회원번호) {
		BusinessResult br = null;
		try {
			br = 회원업무구현.회원을조회하다(회원번호);//얘도 BusinessResult return 이다.
			
		} catch (Exception e) {
			if(e instanceof TransactionSystemException) {
				return new BusinessResult(RESULTCODE.NETWORK_ERROR,"네트워크에 장애가 있습니다.");
			}
		}
		return br;
	}

	@Override
	public BusinessResult 회원프로필을조회하다(int 회원번호) {
		BusinessResult br = null;
		try {
			br = 회원업무구현.회원을조회하다(회원번호);//얘도 BusinessResult return 이다.
			
		} catch (Exception e) {
			if(e instanceof TransactionSystemException) {
				return new BusinessResult(RESULTCODE.NETWORK_ERROR,"네트워크에 장애가 있습니다.");
			}
		}
		return br;
	}

}

4. Control

@Controller
public class 회원등록컨트롤{
	@Autowired @Qualifier("회원업무") I회원업무 회원업무;

	@GetMapping("member")
	public String 회원등록준비하다() {
		BusinessResult br = 회원업무.회원등록준비하다();
		if(br.getCode() != RESULTCODE.정상) {}//비정상처리
		
		return "회원등록창";
	}
	
	@PostMapping("member")
	public ModelAndView 회원등록하다(@ModelAttribute Member member,HttpSession session) {
		ModelAndView mv = null;
		try {
			BusinessResult br = 회원업무.회원등록하다(member);
			if(br.getCode() != RESULTCODE.정상) {
				if(br.getCode() != RESULTCODE.NETWORK_ERROR) {
					mv = new ModelAndView();
					mv.addObject("message", br.getMessage());
					mv.setViewName("/info");
				}
				
			}//비정상처리
			//정상처리
			//경로지정
			mv = new ModelAndView();
			mv.addObject("name",member.getName());
			mv.setViewName("회원등록결과");
		} catch (Exception e) {e.printStackTrace();}
		return mv;
	}
	
	@RequestMapping("member/{no}")
	public ModelAndView 회원을조회하다(@PathVariable("no")int 회원번호) {
		BusinessResult br = 회원업무.회원을조회하다(회원번호);
		if(br.getCode() != RESULTCODE.정상) {}//비정상처리
		
		ModelAndView mv = new ModelAndView();
		mv.addObject("findedMember", (Member)br.getValue());
		mv.setViewName("회원상세창");

		return mv;
	}
	
	@RequestMapping("member2/{no}")
	public ModelAndView 회원프로필을조회하다(@PathVariable("no")int 회원번호) {
		BusinessResult br = 회원업무.회원을조회하다(회원번호);
		if(br.getCode() != RESULTCODE.정상) {}//비정상처리
		Member findedMember = (Member)br.getValue();
		
		//그림을 문자열로 바꿔 간다.
		ModelAndView mv = new ModelAndView();
		mv.addObject("findedMember", findedMember);
		String profile = Base64.encodeBytes(findedMember.getProfile());
		mv.addObject("profile", profile);
		mv.setViewName("회원상세창2");

		return mv;
	}
}