2023. 6. 22. 21:41ㆍTIL(Today I Learned)
(1) 트랜잭션(@Transactional)
- 여러개의 쿼리문이 처리되도 하나의 트랜잭션으로 처리할 때, service가 한꺼번에 처리해야 한다.
- 즉, 하나의 서비스에서 여러개의 dao를 실행한다.
- 예를 들어 게시판 기능에서 게시글 상세조회가 실패한다해도 조회수가 알아서 증가하게 된다.
- 무조건 조회수가 증가하게 되는데, @Transactional을 달아주면 몇개의 dao가 들어오든 그 중 하나가 error가 나면 rollback처리 된다.
- 원하는 대로 하나의 트랜잭션으로 동작하게 된 것이다. 메소드 안쪽에서 예외가 발생하면 rollback이 처리되고, 예외가 발생하지 않으면 commit이 된다.
- 조회수 증가, 상세 조회 두가지 기능이 하나의 서비스에 제공이 되는데 하나의 기능마다 하나씩 커밋이 찍히고 있었는데, 이 둘을 감싸고 있는 메소드를 @Transactional로 감싹더니 둘 다 커밋이 찍히는게 아니라 둘 다 끝나고 나서 커밋이 찍히게 변경이 되는 것이다.
- 예외가 발생하지 않고 정상적으로 끝났을 때 커밋하고, 예외가 발생했을 경우에는 롤백을 한다.
- @Transactional(rollbackFor = BadSqlGrammarException.class) -> 이런 식으로 달아주면, 특정 예외에 대해서만 롤백이 가능하다.
- @Transaction() 괄호 안에 달을 수 있는 여러가지 메소드들이 존재한다.
(2) 트랜잭셔널 설정 방법
1. annotation을 통해 추가
- 라이브러리 안에 있는 것을 사용할 때는 어노테이션으로 안된다.
&&Transactional Manager가 하는 일 &&
- 트랜잭셔널 매니저가 다른 클래스에 있는 메소드를 감싸서 사용한다.
- 즉, @Transactional 이 붙어있는 메소드에 찾아가서 예외가 붙어있는 메소드의 예외 처리를 담당한다.
- id의 값을 무조건 transactionManager라 해야 한다. 다르게 하면 작동하지 않는다.
(3) 트랜잭셔널 설정
1. pom.xml
2. Bean 등록 -> root-context.xml에서 진행
3. 어노테이션 활성화
(4) 인터페이스
- Controller, Service, Dao로 작업하고 있는데 예를 들어 Service를 Service2로 바꾸었다고 가정해보자.
- 컨트롤러 객체 안에는 서비스를 가리키는 그런 변수가 있었을 텐데 연결된게 Service가 아니라 Service2이길 원한다는 것이다.
- 그러면 컨트롤러에 가서 서비스 클래스를 수정해야 한다.
-
(5) 암호화(Spring Security)
- db에서 패스워드를 노출하지 않고 암호문을 넣어주는 것을 말한다.
- 암호화라고 만들어주는 것을 암호화, 다시 평문으로 만들어주는 것을 복호화라고 한다.
- 스프링에서 제공해주는 스프링 시큐리티 암호화 알고리즘을 통해 암호화를 진행할 수 있다.
- 암호문을 db에 넣는 방식으로 처리한다.
- 클라이언트가 서버한테 비밀번호 데이터를 전달해주면, 서버에서는 그 비밀번호를 암호화시킨다. 암호화된 데이터를 db에 넣는다.
- 로그인은 클라이언트가 1234를 입력하고 서버에 1234가 전달된다. 클라이언트가 입력한 1234와 디비에서 암호화된 데이터를 서버 측에서 검사해서 일치하면 로그인이 성공하는 것이고, 일치하지 않으면 로그인 실패가 된다.
- 암호화는 시간 지나면 다 뚫릴 수밖에 없다. 암호화 로직은 디비의 값과 클라이언트가 입력한 값을 서버에서 꺼내와서 별도로 비교해줘야 한다.
- 스프링 시큐리티는 글자수도 맞추는 것이 아니고 유저가 어떤 값을 넣든간에 글자수도 동일하지 않고, 서로 다른 값으로 나오게 한다.
- Spring Security는 단방향 암호화 로직을 쓴다. 한번 암호화를 하면 복호화가 안된다.
- 암호화라는 메소드는 있는데, 복호화라는 메소드는 없다. 다시 그 암호를 복호화시키는 메소드는 제공하지 않는다.
(6) 스프링 시큐리티가 제공하는 암호화 객체 사용
1. pom.xml에 스프링 시큐리티 추가
2. bean 등록
(6) 회원가입 암호화 작업 Service 예시 코드
- 두개의 service 클래스를 만들었을 때, 두 클래스 모두 @service 어노테이션을 붙였을 경우 Spring Controller는 어느 서비스로 갈까?
- 인터페이스의 메소드들은 어차피 public이니 그 안에 public을 붙일 필요는 없다.
public int join(MemberVo vo) {
//암호화
String pwd = vo.getPwd();
String newPwd = encoder.encode(pwd);
vo.setPwd(newPwd);
return dao.join(sst, vo);
}
(7) 로그인 데이터 비교 작업 Service 예시 코드
//로그인
@Override
public MemberVo login(MemberVo vo) {
MemberVo loginMember = dao.login(sst, vo);
//비번 일치 여부 체크
//디비에서 가져온 패스워드
String dbPwd = loginMember.getPwd();
//유저가 입력한 팻워드
String userPwd = vo.getPwd();
boolean isMatch = encoder.matches(userPwd, dbPwd);
if(!isMatch) {
throw new RuntimeException("로그인 실패");
}
return loginMember;
}
'TIL(Today I Learned)' 카테고리의 다른 글
2023.07.03 TIL (0) | 2023.07.03 |
---|---|
2023.06.23 TIL (0) | 2023.06.23 |
2023.06.20 TIL (0) | 2023.06.20 |
2023.06.19 TIL (0) | 2023.06.19 |
2023.06.15 TIL(web.xml, root-context.xml, servlet-context.xml 상세 설명) (0) | 2023.06.15 |