Digking's cave

My First Blog Project (11) : 회원가입 / 로그인 처리 완료 본문

Spring/My First Blog Project

My First Blog Project (11) : 회원가입 / 로그인 처리 완료

디깅 2022. 12. 18. 15:19
728x90

# 회원가입시 Ajax를 사용하는 2가지 이유

1. 요청에 대한 응답을 html이 아닌 Data(json)을 받기 위하여

2. 비동기 통신을 하기 위하여

 

resources/static/js

user.js

let index = {
    init: function(){
        $("#btn-save").on("click",()=>{ // 화살표함수 쓰는 이유는 this를 바인딩하기 위해서
            this.save();
        });
        $("#btn-login").on("click",()=>{
            this.login();
        });

    },

    save:function(){

        let data = {
            username: $("#username").val(),
            password: $("#pwd").val(),
            email: $("#email").val()
        };

        // ajax호출시 default가 비동기 호출
        // ajax통신을 이용해서 3개의 데이터를 json으로 변경하여 insert 요청
        // ajax가 통신을 성공하고 json을 리턴해주면 자동으로 자바 오브젝트로 변환해줌
        $.ajax({
            type:"POST",
            url:"/blog/api/user",
            data: JSON.stringify(data), //http body 데이터
            contentType: "application/json; charset=utf-8", // body데이터가 어떤 타입인지(MIME)
//            dataType:"json" // 요청을 서버로해서 응답 왔을 때 기본적으로 모든 것이 문자열인데, 생긴게 JSON이라면 => javascript object로 변경해줌
        }).done(function(resp){
            alert("회원가입 완료되었습니다.");
            location.href = "/blog";
        }).fail(function(error){
            alert(JSON.stringify(error));
        });
    },

    login:function(){
            let data = {
                username: $("#username").val(),
                password: $("#pwd").val()
            };

            $.ajax({
                type:"POST",
                url:"/blog/api/user/login",
                data: JSON.stringify(data), //http body 데이터
                contentType: "application/json; charset=utf-8",
            }).done(function(resp){
                alert("로그인 완료되었습니다.");
                location.href = "/blog";
            }).fail(function(error){
                alert(JSON.stringify(error));
            });
        }
}

index.init();

 

controller/api 패캐지

UserApiController.java

package com.cos.blog.controller.api;

import com.cos.blog.dto.ResponseDto;
import com.cos.blog.model.RoleType;
import com.cos.blog.model.User;
import com.cos.blog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class UserApiController {

    @Autowired
    private UserService userService;

    // HttpSession session 은 import해서도 사용할 수 있고
    // or @Autowired로 받아올 수도 있다(이 경우에는 param에 작성 안해도 사용 가능)
    @Autowired
    private HttpSession session;

    @PostMapping("/api/user")
    public ResponseDto<Integer> save(@RequestBody User user) {
        user.setRoles(RoleType.USER);
        userService.회원가입(user);
        return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);

        // 실제로 db에 insert를 하고 아래에서 return 되면 된다,
//        user.setRoles(RoleType.USER);
//        int result = userService.회원가입(user);
//        return new ResponseDto<Integer>(HttpStatus.OK,result); //자바오브젝트를 json으로 리턴해줌(jackson
    }

    @PostMapping("/api/user/login")
    public ResponseDto<Integer> login(@RequestBody User user, HttpSession session) {
        System.out.println("UserApiController : login 호출");
        User principal = userService.로그인(user);
        if (principal != null) {
            session.setAttribute("principal", principal);
        }
        return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
    }
}

UserRepository.java

package com.cos.blog.repository;

import com.cos.blog.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

// DAO
// 자동으로
// BEAN으로 등록이 되기 때문에 @Repositoy 생략 가능
public interface UserRepository extends JpaRepository<User, Integer> {
    // JPA naming 전략

    // 두가지 방식으로 쿼리를 실행할 수 있다.

    //첫번째
    // Select * from user where username=username(첫번째 param) and password=password(두번째 param))
    User findByUsernameAndPassword(String username, String password);

    //두번째
//    @Query(value ="Select * from user where username=? and password=?",nativeQuery = true)
//    User login(String username, String password);
}

UserService.java

package com.cos.blog.service;

import com.cos.blog.model.User;
import com.cos.blog.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void 회원가입(User user){
        userRepository.save(user);
//        try {
//            userRepository.save(user);
//            return 1;
//        }catch (Exception e){
//            e.printStackTrace();
//            System.out.println("UserService : 회원가입(): "+ e.getMessage());
//        }
//        return -1;
    }

    @Transactional(readOnly = true) //select 할 때 트랜잭션 시작, 서비스 종료시에 트랜잭션 종료(정합성)
    public User 로그인(User user) {

        return userRepository.findByUsernameAndPassword(user.getUsername(),user.getPassword());
    }
}

두가지 방식으로 쿼리를 실행할 수 있다.
1) 쿼리메서드

Select * from user where username=username(첫번째 param) and password=password(두번째 param))

를 표현하기 위해 JPA 네이밍 전략 및 findBy 를 통해 원하는 매개변수로 쿼리 생성


    User findByUsernameAndPassword(String username, String password);

2) @Query
    @Query(value ="Select * from user where username=? and password=?",nativeQuery = true)
    User login(String username, String password);

 

추가 참고 사이트 ) https://wonit.tistory.com/470

 GlobalExceptionHandler.java

package com.cos.blog.handler;

import com.cos.blog.dto.ResponseDto;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

//    @ExceptionHandler(value = IllegalArgumentException.class)
//    public String handleArgumentException(IllegalArgumentException e){
//        return "<h1>" + e.getMessage() +"</h1>";
//    }

    @ExceptionHandler(value = Exception.class)
    public ResponseDto<String> handleArgumentException(Exception e){
        return new ResponseDto<String>(HttpStatus.INTERNAL_SERVER_ERROR.value(),e.getMessage());
//        return "<h1>" + e.getMessage() +"</h1>";
    }
}

 

 

 

반응형