Jumbo96 2023. 10. 10. 14:43
728x90
반응형

★학습목표

1. trabsaction project

2. 글쓰기 + 파일 업로드

   + Board < 데이터저장 

   + Board의 id + 파일 관련 내용 < 저장

         ㄴ 오류 발생

                   ㄴ작업 전 상태로 복구 < @Transaction 

 

write.html에  input 작성

<input type="file" name="file" id="">
    @PostMapping("/writer")
    public String writerPost(
        @ModelAttribute Board board,
        @RequestParam("file") MultipartFile mFile) {
        String originalFilename = mFile.getOriginalFilename();
       
        // 게시글 저장 (+추가된 게시글 번호 획득)
        Board saveboard = boardRepository.save(board);
        //파일 정보 저장
        FileAtch fileAtch = new FileAtch();
        fileAtch.setOriginalName(originalFilename);
        fileAtch.setSaveName(originalFilename);
        fileAtch.setBoard(saveboard);
        fileAtchRepository.save(fileAtch);
       
        return "redirect:/board/write";
    }

board와 fileAtch 둘다 h2에 저장이 되긴한다. 

하지만 

    @PostMapping("/writer")
    public String writerPost(
        @ModelAttribute Board board,
        @RequestParam("file") MultipartFile mFile) {
        String originalFilename = mFile.getOriginalFilename();
       
        // 게시글 저장 (+추가된 게시글 번호 획득)
        Board saveboard = boardRepository.save(board);
        //파일 정보 저장
        FileAtch fileAtch = new FileAtch();
        fileAtch.setOriginalName(originalFilename);
        fileAtch.setSaveName(originalFilename);
        fileAtch.setBoard(saveboard);
        int a = 4 / 0; // 오류 발생
        fileAtchRepository.save(fileAtch);

        return "redirect:/board/write";

이런 경우 board는 저장되고 fileAtch는 저장이 되지 않는다.

 @Transactional  을 추가해주면  board와 fileAtch가 한 묶음?이 되어 하나가 오류가나면 다같이 롤백 된다.

#@Transaction은

RuntimeException 계열에 대해서 RollBack 수행

 

*IOException 발생 시 RollBack 되지 않음

>> rollbackFor 옵션을 사용해서 IOException을 추가로 지정

 

#수행된 결과는 일관성되어야 한다. 뭐는 성공하고 뭐는 오류나지 않게...

 

이러한 경우에는 롤백하지않고 넘기기도 가능하다

    @Transactional(
        noRollbackFor = {ArithmeticException.class})
        //ArithmeticException은 롤백x

# 제외,생략

ignore

exclude

no XXX 등 

 

    @Transactional(
        rollbackFor = {ArithmeticException.class})
        //이런 경우는 롤백 해

최고 부모 {Exception.class} 를 지정해주면 모든 경우에 롤백이 된다.

@Controller
@Transactional(
        rollbackFor = { ArithmeticException.class })
@RequestMapping("/board")
public class BoardController {

class에 달아두면 메소드별로 각각 Transaction이 적용된다.

 

//// 새로운 파일 시작

 

비밀번호 암호화

1. 스프링 시큐리티 의존성 추가, Config 추가

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
@Configuration
public class SecurityConfig {
   
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

2. 시큐리티의 "기본 설정"을 무효화

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

3. encode(), matches() 지원

 

로그인 코드 수정

1. Email로 데이터를 조회하는 메소드 작성

    UserRepository에서 findByEmail() 메소드 작성

 

2. findByEmail() 조회 후 

    PasswordEncoder의 matches 메소드로 비밀번호 비교

    @PostMapping("/signin")
    public String signinPost(@ModelAttribute User user) {
        User dbUser =
            userRepository.findByEmail(user.getEmail());
       
        String encodedPwd = dbUser.getPwd();
        String userPwd = user.getPwd();

        boolean isMatch =
        passwordEncoder.matches(userPwd, encodedPwd);
        if(isMatch) {
            session.setAttribute("user_info", dbUser);
        }
        return "redirect:/";
    }

dbUser와 userPwd를 비교하여 로그인

 

로그인 후 기능 사용

1. 인터셉터 적용

2. 로그인 후 기능 사용가능하게 설정

   + config 파일 작성

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private SigninCheckInterceptor signInCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(signInCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/signin", "/signup",
                "/");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

 # "/" 메인화면 , "signin" 로그인 , "signup" 회원가입 은 들어가야 하니 제외

 + interceptor 파일 작성

    @Override
    // pre는 앞에서 작업 요청
    public boolean preHandle(
            HttpServletRequest request, HttpServletResponse response,
            Object handler) throws Exception {
        log.debug("preHandle");
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user_info"); //user_info 는 세션에 등록된 이름
        //dbuser 의 클래스 명을 입력 (User dbUser = ) User!!!
        if (user == null) {
            response.sendRedirect("/signin");
             // AJAX 기술을 사용하면 동작이 더 부드러워짐
            return false;
        }
        return true;
    }

오늘은 여기까지 학습을 했고...

이제 배운것들에 대해 평가가 들어간당.. 

수요일 목요일은 평가당..

평가 요구사항! 

1. 회원가입 기능 구현 • 이름, 비밀번호, 이메일 주소, 전화번호, 가입일자 저장

2. 로그인 기능 구현

3. 회원가입과 로그인에 필요한 비밀번호는 암호화

4. 게시물 등록

5. 등록된 사용자의 정보는 수정 가능

을 기반으로 만들고 시간이 남으면 추가기능을 넣을 예정이다

 

 

# 앞으로 확인해야 할 것들..

1. 채팅(자바,웹) . socket 기술 사용

2. jwt 인증방식

3. 스프링 시큐리티 (심화,복잡)

 

728x90
반응형