본문 바로가기

프로젝트/개인

7. 회원가입 세팅+ api없는 회원가입

이 전글에서 이야기 했듯

이번 프로젝트에서는 모든 데이터를 json 방식으로 넘겨  ajax로 처리할것

이유!

더보기

Ajax를 사용하는 첫번째 이유 : 일반적으로 서버로 부터 응답받을때 웹은 HTML파일을 받고 앱은 데이터(JSON)를 받는다. 

이것은 서버를 이원화하여 구축한 것을 의미하며 이때 '서버를 통합하여 각각의 클라이언트에게 응답해줄순 없을까?'라는 의문점에서 고안된 방법이 Ajax통신이다.

Ajax통신을 사용하면 웹은 서버로부터 데이터(JSON)를 리턴받을 수 있으며 그렇게 되면 서버의 분리 필요없이 하나의 서버로 각각의 클라이언트 요청을 받아 응답해줄수 있게된다.

대신 웹클라이언트는 추가적인 요청을 통해 HTML파일을 받아야한다.

 

Ajax를 사용하는 두번째 이유 : 비동기 통신을 하기 위해서이다.(순서에 상관없이)

절차적 통신 => 속도가 느려져서 사용자 경험이 나빠짐

5번을 하던 중 pending이 완료되서 다시 4번으로 돌아가는 것이 바로 call baxk

 

'비동기'를 쉽게 설명한 그림, 저 숙제를 하던 중 다시 돌아가서 라면을 마저 끓이는게 call back!

 

 

 

=> form method="post" 이거 xx

joinForm의 회원가입버튼, script를 저렇게 만들어놓고
js파일만들기

let index = {
		init: function(){

}

index.init();

변수를 만들고, 

혹시 오류나면 console에 오류 이름보고, 그다음 network에서 f5해서 무슨 오류인지 확인!

 

user.js

let index = {
	init: function(){
		$("#btn-save").on("click", ()=>{
			// function(){} 아니고 ()=>{}? this를 바인딩하기 위해서!!
			// 그냥 function 쓰면 this 는 window객체를 가리킴
			this.save();
		});

	},

	save: function(){
		//alert('user의 save함수 호출됨');
		let data = {
			username: $("#username").val(),
			password: $("#password").val(),
			email: $("#email").val()
		};

		//console.log(data);

		// ajax호출시 default가 비동기 호출
		// ajax 통신을 이용해서 3개의 데이터를 json으로 변경하여 insert 요청!!
		// ajax가 통신을 성공하고 서버가 json을 리턴해주면 자동으로 자바 오브젝트로 변환: dataType: "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오브젝트로 변경
		}).done(function(resp){//.done: 요청 정상일때 실행
			if(resp.status === 500){
				alert("회원가입에 실패하였습니다.");
			}else{
				alert("회원가입이 완료되었습니다.");
				location.href = "/blog";
			}

		}).fail(function(error){//.done: 요청 실패일때 실행
			alert(JSON.stringify(error));
		});

	},

}

index.init();

 

UserService

package com.cos.blog.service;

import com.cos.blog.model.RoleType;
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 javax.transaction.Transactional;

//스프링이 컴포넌트 스캔을 통해서 Bean에 등록을 해줌. == Ioc를 해준다
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Transactional
    public int 회원가입(User user){

        user.setRole(RoleType.USER);
        try {
            userRepository.save(user);
            return 1;
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("UserService: 회원가입() :"+e.getMessage());
        }
        return -1;
    }
}

응답받은 데이터 타입과 응답상태를 ResponseDto로 받음

ResponseDto

package com.cos.blog.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ResponseDto<T> {
    int status;
    T data;
}

 

UserApiController

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;

@RestController //data만 리턴해줄거
public class UserApiController {

	@Autowired
	private UserService userService;
	@PostMapping("/api/user")
	public ResponseDto<Integer> save(@RequestBody User user) { // username, password, email
		System.out.println("UserApiController : save 호출됨");
		user.setRole(RoleType.USER);
		userService.회원가입(user);
		return new ResponseDto<Integer>(HttpStatus.OK.value(), 1); // 자바오브젝트를 JSON으로 변환해서 리턴 (Jackson)
	}


}

handler도 수정해줘야함! 안그러면 모든 오류 얘가 채가서 정확한 exception 알수없음

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 : 이 컨트롤러가 어떤 클래스에서 exception이 발생하든 처리 가능하다
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
//    모든 에러를 스프링이 감지해서 이 메소드로 보내줌
//    @ExceptionHandler(value = Exception.class)
//    public String handleArgumentException(Exception 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()); // 500
    }

}