[포트폴리오 페이지]_7단계_회원가입 구현(feat.oracle)

2022. 3. 31. 20:12[Spring]_/[Spring]_포트폴리오 페이지 만들기

728x90
반응형

[환경]

 

개발툴 : IntelliJ

DB : oracle

프레임워크 : spring , mybatis

 

----

개발 목표 : 오라클 디비를 이용해서 회원가입 기능 만들기.

 

완성화면]

 

회원가입 버튼 클릭시 팝업창 오픈]

 

팝업창 기능]

1. 아이디 중복확인 -> DB 조회

2. 패스워드 일치 확인

3. 가입버튼 클릭시 DB insert 및 팝업창 닫힘

입력된 DB 모습]

 

소스코드 및 설명]

 

팝업창 오픈 코드]

$('.authjoin').click(function(){
    window.open('auth/authjoin.do', 'windowPop', 'width=400, height=600, left=400, top=400, resizable = yes')

});

open 메소드 사용 

첫번째 파라미터로 열릴 url -> controller의 requestmapping으로 전달 하여 jsp 파일 호출,

그 뒤의 파라미터는 사이즈 크기, 조절가능여부 부여

 

Controller 부분]

@RequestMapping("auth/authjoin.do")
public String authJoin() {return "join/authjoin";}

간단하게 jsp 파일 위치를 리턴

 

팝업 Jsp 파일]

<script>

    let initialize = function () {

        let authcheckbtn = document.querySelector('.id_name_checkauth');
        let idtext = document.querySelector('.id_input');
        let pwtext = document.querySelector('.pw_input');
        let pwcheck = document.querySelector('.pwck_input');
        let idexist = document.querySelector('.id_input_exist');
        let joinbtn = document.querySelector('.join_button');




        pwcheck.onchange = function(){

            if(pwtext.value == pwcheck.value){
                $('.pw_input_correct').css("display","inline-block"); // 사용할 수 있습니다.
                $('.pw_input_incorrect').css("display", "none");
            } else{
                $('.pw_input_incorrect').css("display","inline-block"); // 사용할 수 없습니다.
                $('.pw_input_correct').css("display", "none");
            }
        }


        authcheckbtn.onclick = async function () {

                let chk = await authCheck();

                if(chk.state == 'success'){
                    $('.id_input_correct').css("display","inline-block"); // 사용할 수 있습니다.
                    $('.id_input_incorrect').css("display", "none");
                } else {
                    $('.id_input_incorrect').css("display","inline-block"); // 사용할 수 없습니다.
                    $('.id_input_correct').css("display", "none");
                }

        }

        joinbtn.onclick = async function(){

            let chk = await authCheck();
            if(pwtext.value !== pwcheck.value){
                alert('비밀번호가 일치하지 않습니다. 다시 확인해 주세요')
                return;
            }
            if(chk.state == 'fail'){
                $('.id_input_exist').css("display","inline-block");
                return;
            }

            authJoin();
            opener.parent.location.reload();
            window.close();

        }


        function authJoin() {

            fetch("/auth/authjoin.do",{
                method: 'POST',
                headers: {
                    'content-type' : 'application/json'
                },
                body: JSON.stringify({
                    ID :idtext.value,
                    PW :pwtext.value
                })
            });
        }

        function authCheck() {

                let id = idtext.value;
                let response = fetch("/join/authjoincheck.do",{
                    method : 'POST',
                    headers: {
                        'content-type' : 'application/json'
                    },
                    body: JSON.stringify({
                        memberId : id
                    })
                });
                return response.then(res=> res.json());
            }


    }

    $(function () {
        initialize();
    });
</script>

비밀번호 일치 여부 -> onchange 를 사용하여 변화될 때 마다 비교하도록 설정

                              해당 상황시 jquery로 선택하여 css 를 변경 display : none 부여시 보이지 않고, inline-block 부                                여시 화면에 표시

 

1. 중복확인]

authcheckbtn.onclick = async function () {

                let chk = await authCheck();

                if(chk.state == 'success'){
                    $('.id_input_correct').css("display","inline-block"); // 사용할 수 있습니다.
                    $('.id_input_incorrect').css("display", "none");
                } else {
                    $('.id_input_incorrect').css("display","inline-block"); // 사용할 수 없습니다.
                    $('.id_input_correct').css("display", "none");
                }

        }

 

 

해당 함수는 중복확인 함수이다.

await 를 걸어둔 authCheck 함수를 호출한다

 

authCheck()

function authCheck() {

        let id = idtext.value;
        let response = fetch("/join/authjoincheck.do",{
            method : 'POST',
            headers: {
                'content-type' : 'application/json'
            },
            body: JSON.stringify({
                memberId : id
            })
        });
        return response.then(res=> res.json());
    }

fetch를 사용하였다. 입력한 value를 받아서 post 형식으로 컨트롤러에 전달한다.

전달시 JSON.stringify 를 이용하여 json 파일로 묶어서 보내주어야 한다.

fetch는 기본적으로 promise를 반환하기 때문에 통신성공시 then 함수 안에

json() 으로 풀어줘야 한다. 변수에 집어넣거나 사용시 반드시 json()을 활용해야 한다.

 

autocheck 가 호출하는 controller 부분]

//아이디 중복검사
@RequestMapping("/join/authjoincheck.do")
@ResponseBody
public HashMap<String, Object> memberIdChkPOST(@RequestBody Map<String,String> map) throws Exception{
    System.out.println("memberId 테스트 = " + map);
    String memberId = map.get("memberId");
    System.out.println("memberId 테스트 = " + memberId);

    int result = memberservice.idCheck(memberId);


    HashMap<String, Object> resultMap = new HashMap<String, Object>();


    if(result != 0) {
        resultMap.put("state", "fail");
        // 중복 아이디가 존재
    } else {
        resultMap.put("state", "success");
        // 중복 아이디 x
    }

    JSONObject returnresult = new JSONObject(resultMap);
    return returnresult;
}

보낼때 Json 형식의 파일로 보냈기 때문에 requestbody의 부분은 Map 함수를 이용해서 키와 value를 나눠서 받도록 설정하였고, 받아온 값 에서 memberId의 키값의 value 만을 서비스에 전달하고 그 결과를 이용해서 판별후 json으로 묶어 다시 전달한다.

 

해당 서비스 인터페이스]

public int idCheck(String memberId) throws Exception;

해당 인터페이스 구현체]

@Override
public int idCheck(String memberId) throws Exception {

    return membermapper.idCheck(memberId);
}

위의 코드에서 알수 있는 점은 mapper 을 거쳐서 돌려주는 값은 int 형이고, 받는 파라미터는 string 타입이란 점이다.

 

해당 mapper 인터페이스]

public int idCheck(String memberId);

마찬가지로 받는값과 돌려주는 값이 명시되어 있다.

 

해당 기능 mapper.xml ]

<select id="idCheck" resultType="int">

    select count(*) from auth where memberId = #{memberId}

</select>

쿼리문이 작성되어 있다, 전체를 검색해서 해당 아이디와 같은 값의 수를 리턴한다.

 

다시 컨트롤러로 돌아오면, 같은 아이디가 있는 만큼의 수를 반환하고, 만약 아이디가 중복되지 않는다면 0을 리턴할 것입니다.

따라서 컨트롤러 하단의 if문을 작성하여 해당 값을 fetch를 사용하였기 때문에 json으로 묶어서 보내줍니다.

 

다시 view 단]

 

authcheckbtn.onclick = async function () {

        let chk = await authCheck();

        if(chk.state == 'success'){
            $('.id_input_correct').css("display","inline-block"); // 사용할 수 있습니다.
            $('.id_input_incorrect').css("display", "none");
        } else {
            $('.id_input_incorrect').css("display","inline-block"); // 사용할 수 없습니다.
            $('.id_input_correct').css("display", "none");
        }

}

그 값을 await -> 즉 통신이 다 될때 까지 기다린 다음에 다음 row를 진행합니다.

. 을 이용해서 key를 참조할 수 있습니다.

그값이 성공이면 사용가능하다는 css 표현을 만약 중복시 불가하다는 css를 표현합니다.

 

2. 회원가입]

joinbtn.onclick = async function(){

    let chk = await authCheck();
    if(pwtext.value !== pwcheck.value){
        alert('비밀번호가 일치하지 않습니다. 다시 확인해 주세요')
        return;
    }
    if(chk.state == 'fail'){
        $('.id_input_exist').css("display","inline-block");
        return;
    }

    authJoin();
    opener.parent.location.reload();
    window.close();

}

해당 함수는 상단의 authcheck를 한뒤 중복체크를 해줍니다.

 

authJoin() ]

function authJoin() {

    fetch("/auth/authjoin.do",{
        method: 'POST',
        headers: {
            'content-type' : 'application/json'
        },
        body: JSON.stringify({
            ID :idtext.value,
            PW :pwtext.value
        })
    });
}

같은 fetch를 사용하였고

json 형태의 값 2개를 파라미터로 보냅니다.

 

controller]

// 회원가입
@RequestMapping(value="/auth/authjoin.do", method= RequestMethod.POST)
@ResponseBody
public String JoinAuth(@RequestBody Map<String,String> map) throws Exception{


    String ID = map.get("ID");
    String PW = map.get("PW");
    MemberVO member = new MemberVO();
    System.out.println("ID = " + ID);

    member.setMemberId(ID);          //회원 id
    member.setMemberPw(PW);          //회원 비밀번호

    System.out.println("jsonElement\n = " + map);

    memberservice.memberJoin(member);
    return "";
}

위와 동일하게 map으로 받고 string을 리턴합니다. -> void로 해도 무방

받아온 json을 ID 와 PW로 구분한 뒤,

VO 객체의 member을 선언하고 setMemberId, pw 함수를 통해 각각의 값을 집어넣습니다 (Setter Getter)

그리고 그 객체를 서비스 부분으로 전송합니다.

 

VO]

public class MemberVO {
    private String memberId;

    @Override
    public String toString() {
        return "MemberVO{" +
                "memberId='" + memberId + '\'' +
                ", memberPw='" + memberPw + '\'' +
                '}';
    }

    private String memberPw;

    public String getMemberId() {
        return memberId;
    }

    public void setMemberId(String memberId) {
        this.memberId = memberId;
    }

    public String getMemberPw() {
        return memberPw;
    }

    public void setMemberPw(String memberPw) {
        this.memberPw = memberPw;
    }
}

 

서비스-mapper의 부분은 동일한 구조로 생략

 

mapper.xml ]

<insert id="memberJoin">
    insert into book_member values(#{memberId}, #{memberPw} )

</insert>

insert 쿼리를 날리고 받아온 값의 key값을 전달합니다.

insert 문이기 때문에 다른 resulttype이 없습니다.

 

다시 view 단]

 

opener.parent.location.reload();
window.close();

가입하기 버튼의 마지막인 부모의 주소로 reload 함과 동시에 팝업을 close 합니다.

 

감사합니다.

728x90
반응형