ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Thymeleaf를 이용해 Option값 받아오기.
    졸업과제/BackEnd 2023. 3. 11. 15:13

    회원가입할 때 사용자가 이메일 도메인을 선택하면 선택한 도메인과 이메일 주소를 연결해서 DB에 저장하는 것과

    게시물 작성할때 사용자가 자신이 거주하고자 희망하는 지역의 방 주소를 선택하면 방 주소가 게시물 DB에 반영되는 것

    2가지를 진행하려고 한다. 

     

    2개의 기능다 html코드에서 Option태그를 이용해 사용자가 선택할 수 있도록 작성되어 있다.

    오늘은 Option태그 값이 Controller, Service, Repository까지 전달될 수 있도록 구현할 예정이다.


     

     

    회원가입 시 이메일과 도메인 연결.


    Controller

    public class SignController{
    
        /** 회원가입 GET,POST 매핑 관련 Controller**/
    
        @GetMapping(value = "/members/new")
        public String signUp(Model model)
        {
            logger.info("[signUp] GET 회원가입 컨트롤러 동작 ");
            SignUpRequestDto signUpRequestDto = new SignUpRequestDto();
            model.addAttribute("dto",signUpRequestDto);
            return "join";
        }
    
    
        @PostMapping(value = "/members/new")
        public String signUp(@Valid SignUpRequestDto dto, Model model)
        {
            logger.info("[signUp] POST 회원가입 컨트롤러 동작");
            logger.info("[signUp] name:{}, nickname:{}, email:{}",dto.getName(),dto.getNickname(), email);
            dto.setRole("user");
            SignUpResultDto signUpResultDto = signService.signUp(dto);
    
            SignInRequestDto signInRequestDto = new SignInRequestDto();
            model.addAttribute("SignInRequestDto",signInRequestDto);
            return "member/login";
        }
    }

    오늘 구현했던 기능들은 Controller, Service로직들이 간단해서 다행이었다.

    GetMapping 할 때에는 회원가입 시 필요한 정보들을 담아올수 있는 Dto를 생성해서 전달한다. Dto에는 사용자의 이름, 아이디, 비밀번호, 이메일 등등 회원가입시 필요한 전반적인 정보들을 필드로 가지고 있다.

     

    PostMapping시에는 사용자가 회원가입 양식에 작성한 데이터를 담고 있는 Dto를 Service에 전달해서 DB에 반영될 수 있도록 해준다.


    Service

    public class SignService 
    {
            @Override
            public SignUpResultDto signUp(SignUpRequestDto signUpRequestDto){
                SignUpResultDto signUpResultDto = new SignUpResultDto();
                logger.info("[getSignUpResult] 회원 가입 정보 전달");
    
                String tempEmail = signUpRequestDto.getEmail()+"@"+signUpRequestDto.getDomain();
                User user;
                if(signUpRequestDto.getRole().equals("admin")) {
                    user = User.builder()
                            .uid(signUpRequestDto.getId())
                            .name(signUpRequestDto.getName())
                            .password(passwordEncoder.encode(signUpRequestDto.getPassword()))
                            .nickname(signUpRequestDto.getNickname())
                            .email(tempEmail)
                            .phoneNum(signUpRequestDto.getPhoneNum())
                            .roles(Collections.singletonList("ROLE_ADMIN"))
                            .build();
                }else{
                    user = User.builder()
                            .uid(signUpRequestDto.getId())
                            .name(signUpRequestDto.getName())
                            .password(passwordEncoder.encode(signUpRequestDto.getPassword()))
                            .nickname(signUpRequestDto.getNickname())
                            .email(tempEmail)
                            .phoneNum(signUpRequestDto.getPhoneNum())
                            .roles(Collections.singletonList("ROLE_USER"))
                            .build();
                }
    
                User savedUser = userRepository.save(user);
    
                logger.info("[getSignUpResult] userEntity 값이 들어왔는지 확인 후 결과 값 주입");
                if(!savedUser.getName().isEmpty())
                {
                    logger.info("[getSignResult] 정상 처리 완료");
                    setSuccessResult(signUpResultDto);
                }else {
                    logger.info("[getSingUpResult] 실패 처리 완료");
                    setFailResult(signUpResultDto);
                }
                return signUpResultDto;
            }
        }

    오늘 중요했던 거는 이메일과 도메인을 연결시켜줘야 했기 때문에 Service코드에 코드를 한 줄 추가해 줬다.

    html에서 이메일. 즉 @앞에는 사용자가 직접 타이핑으로 적을 수 있도록 하였고 @뒤에 도메인은 Option값으로 사용자가 선택할 수 있도록 해주었기 때문에 두 개의 값들을 각각 dto에서 다른 필드 값으로 받아올 필요가 있었다.

     

    String tempEmail = signUpRequestDto.getEmail()+"@"+signUpRequestDto.getDomain();
    

    그렇기 때문에 위의 코드처럼 email과 domain을 연결시켜 줘서 새로운 문자열로 만든 뒤 user객체를 생성해준 뒤 DB에 반영시켜 주었다.


    html

    <h5>이메일</h5>
    <div class="join__column" id="join_email">
        <input type="text" class="form-control" th:field="*{email}" placeholder="이메일" aria-label="email" aria-describedby="button-addon2" required>
        <div class="input-group">
            <select class="custom-select" th:field="*{domain}" aria-label="Example select with button addon">
                <option value="">-선택-</option>
                <option th:value="naver.com">naver.com</option>
                <option th:value="gmail.com">gmail.com</option>
                <option th:value="hanmail.net">hanmail.net</option>
                <option th:value="hotmail.com">hotmail.com</option>
                <option th:value="korea.com">korea.com</option>
                <option th:value="nate.com">nate.com</option>
                <option th:value="yahoo.com">yahoo.com</option>
            </select>
        </div>
    </div>

    사용자가 작성하는 이메일칸은 dto의 이메일 필드에 저장시켜 주고 사용자가 선택한 도메인은 domain필드에 따로따로 저장시켜 주어

    Service에서 두 개의 문자열이 합쳐질 수 있도록 구현하였다.


    test

    사용자가 작성한 qwer1234와 뒤에 Option태그로 선택한 naver.com도메인주소가 연결되어 DB에 반영되는 것을 확인하였다.


     

     

    게시물 작성할 때 주소 데이터 DB반영


    Enum

    public enum AreaEnum {
        강남구, 강동구, 강북구, 강서구, 관악구, 구로구, 금천구,
        노원구, 도봉구, 동대문구, 동작구, 마포구, 서대문구, 서초구, 성동구, 송파구, 양천구,
        영등포구, 용산구, 은평구, 종로구, 중구, 중랑구
    }

    서울시에 있는 모든 구를 Enum타입으로 정의해 준다. Enum타입으로 정의한 뒤 이따 html코드에서 Thymeleaf 반복문을 이용해

    Option값들을 출력하고 값을 전달할 것이다.


     

     

    Controller

    public class PostController
    {
        /**전세 타입의 게시물 GET, POST 매핑**/
        @GetMapping("/writeBeforePay")
        public String writeBeforePay(Model model){
    
            logger.info("[postWriteMouth] GET 게시물 전세 작성 Controller 동작.");
            LeasePostRequestDto leasePostRequestDto = new LeasePostRequestDto();
            model.addAttribute("dto",leasePostRequestDto);
            model.addAttribute("areaEnum",AreaEnum.values());
            return "writeBeforePay";
        } // 전세 타입의 post
    
        @PostMapping("/writeBeforePay")
        public String writeBeforePay(LeasePostRequestDto dto,MultipartFile file) throws Exception
        {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Object principal = authentication.getPrincipal();
            User user = (User)principal;
    
            logger.info("[postWriteMouth] POST 게시물 전세 작성 Controller 동작.");
    
            PostUpResultDto postUpResultDto = postService.LeasePostWrite(dto, file, user.getUid());
    
            logger.info("[postWriteMouth] ResultDto 결과: {}, {}, {}",postUpResultDto.getCode(),postUpResultDto.getMsg(),postUpResultDto.getContext());
            return "redirect:/";
    
        }
    }

    PostMapping은 과거에 정리했던 것과는 달라진 것이 없다.

    GetMapping을 할 때가 살짝 달라졌는데 위에서 정의했던 Enum을 Model에 실어서 전달시켜준다.

    Enum.values ( ) 메서드를 이용해 해당 Enum객체가 가지고 있는 모든 값들을 배열형태로 전달시켜 준다.


    View

    <div class="input-group">
      <select class="custom-select" th:field="*{area}" aria-label="Example select with button addon" required>
        <option th:each="area: ${areaEnum}" th:value="${area}" th:text="${area}">-지역선택-</option>
      </select>
    </div>

    원래는 Enum타입에서 정의했던 서울의 모든 구가 Option태그에 감싸져 있는 상태로 쭈욱 나열되어 있었는데 이렇게 한 줄로 줄었다!

     

    select 태그 안에 있는 th:field속에 area는 사용자가 지역을 선택하면 해당 지역의 데이터가 실려질 dto안에 있는 area필드이다.

    option태그 안에있는 area들은 Controller에서 전달했던 areaEnum.values( )의 값들을 의미하며 정의했던 enum타입의 값들 중 하나를 사용자가 선택하면 th:field에 담아준다.


     

    test

    사용자가 지역을 선택하려고 클릭하면 Enum타입으로 정의해 줬던 값들이 잘 출력되는 모습을 확인할 수 있다.

    종로구를 선택했을 때 DB에 종로구가 저장되는 것을 확인하였다.


    이메일을 생성할 때 이메일과 도메인을 연결하는 방식이 좋은 방법인지는 모르겠다. 분명히 html에서 연결할 수 있을 거 같은데 

    좀 더 고민해 보아야겠다.

    댓글

Designed by Tistory.