250x250
Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 프로그래머스 알고리즘
- 안드로이드 sunflower
- 주택가 잠실새내
- 프래그먼트
- 막내의막무가내 안드로이드
- 막내의막무가내 rxjava
- 부스트코스
- 안드로이드
- 2022년 6월 일상
- 막내의 막무가내
- 막내의막무가내 안드로이드 코틀린
- 주엽역 생활맥주
- Fragment
- 막내의막무가내 코볼 COBOL
- 부스트코스에이스
- 막내의막무가내 플러터 flutter
- 막내의막무가내 일상
- flutter network call
- 안드로이드 Sunflower 스터디
- 막내의막무가내 코틀린
- 막내의 막무가내 알고리즘
- 막내의막무가내 안드로이드 에러 해결
- 막내의막무가내 SQL
- 막내의막무가내
- 막내의막무가내 프로그래밍
- 막무가내
- 막내의막무가내 플러터
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 목표 및 회고
- 막내의막무가내 알고리즘
Archives
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[Spring boot] 회원가입 기록 AWS(EC2, MySql) - JPA - Thymeleaf 본문
728x90
스프링부트에서는 회원가입할때 스프링 시큐리티라고 보안관련 암호화하는 방법을 사용하나보다. 읽어보긴 했지만 적용하기엔 저같은 초심자한텐 무리이므로 나중에 해보도록 하겠습니다.
ajax 통신을 사용하여 회원가입 로직을 구현해 본 것을 기록해볼려고 합니다.
차근차근 첨부터 공부한게 아니여서 실습으로 배우면서 하는거라 이상한점이 있어도 양해 부탁드립니다. ㅎㅎ
막무가내 프로그래밍입니다. ㅎㅎ
[프로젝트 구조]
[컨트롤러]
map 으로 받을 때는 @ResponseBody 붙여주도록 하자.
package com.mtjin.itarticle.controller;
import com.mtjin.itarticle.UserDto;
import com.mtjin.itarticle.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Controller
@AllArgsConstructor
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView goLogin( HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
mv.setViewName("views/login/login");
return mv;
}
//Map 형태 ResponseBody 어노테이션 필요 객체 Body로 받아야함
@ResponseBody
@RequestMapping(value = "/do_register", method = RequestMethod.POST)
public Map<String, String> doRegister(@ModelAttribute(name = "userDto") UserDto userDto) {
System.out.println(userDto.toString());
Map<String, String> map = new HashMap<>();
try {
map.put("email", "true");
map.put("name", "true");
if (userService.isExistEmail(userDto)) {
map.put("email", "false");
map.put("success", "false");
} else if (userService.isExistName(userDto)) {
map.put("name", "false");
map.put("success", "false");
} else {
userService.saveUser(userDto);
map.put("success", "true");
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
@ResponseBody
@RequestMapping(value = "/register", method = RequestMethod.GET)
public ModelAndView goRegister() {
ModelAndView mv = new ModelAndView();
mv.setViewName("views/login/register");
return mv;
}
@RequestMapping(value = "/forgot", method = RequestMethod.GET)
public ModelAndView goForgot() {
ModelAndView mv = new ModelAndView();
mv.setViewName("views/login/forgot");
return mv;
}
@RequestMapping(value = "/reset", method = RequestMethod.GET)
public ModelAndView goReset() {
ModelAndView mv = new ModelAndView();
mv.setViewName("views/login/reset");
return mv;
}
}
[레포지토리]
이메일, 이름이 DB에 있는지 확인하는 함수 추가 (JpaRepository 의 기능을 사용 -> find~ )
되게 좋은 것 같습니다. 안드로이드의 Room 과 좀 비슷한 것 같습니다.
서비스에서 사용하는 save의 경우는 ORM으로 맵핑되서 저장되는데 Reposiory에 구현안해놔도 처음부터 사용이 가능하다. 이것또한 JPA의 기능..
package com.mtjin.itarticle.domain.repository;
import com.mtjin.itarticle.domain.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserRepository extends JpaRepository<UserEntity, Long> {
List<UserEntity> findUserEntityByEmail(String email);
List<UserEntity> findUserEntityByName(String name);
}
[서비스]
DTO를 건네받아 레포지토리에 엔티티로 맵핑하여 사용
package com.mtjin.itarticle.service;
import com.mtjin.itarticle.UserDto;
import com.mtjin.itarticle.domain.repository.UserRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@AllArgsConstructor
@Service
public class UserService {
private UserRepository userRepository;
@Transactional
public Long saveUser(UserDto userDto) {
return userRepository.save(userDto.toEntity()).getId();
}
@Transactional
public boolean isExistEmail(UserDto userDto) {
return !userRepository.findUserEntityByEmail(userDto.toEntity().getEmail()).isEmpty();
}
@Transactional
public boolean isExistName(UserDto userDto) {
return !userRepository.findUserEntityByName(userDto.toEntity().getName()).isEmpty();
}
}
[register.js]
회원가입 성공 시 로그인 페이지로 리다이렉트를 합니다.
이미 아이디나 이메일 있을 경우 알림창 띄워줍니다. 이것 때문에 ajax 통신 사용
정규식 검사도 실행 (밑 코드에는 없습니다)
function ajax_register() {
var register_form = $("#register_form").serialize();
alert("Aaaa");
$.ajax({
type: 'POST',
url: 'do_register',
data: register_form,
dataType: 'json',
success: function (json) {
if (json.success === "true") {
Swal.fire({
title: "Success!",
text: "Congratulations, Register Success",
icon: "success"
}).then(function() {
// 성공시 확인 버튼 클릭 후 login 페이지로 리다이렉트
window.location.href = "login";
});
} else {
if (json.name === "false") {
//이미 존재하는 이름
Swal.fire({
title: 'Fail', /*상단 타이틀*/
text: 'Name is already Exist', /*내용*/
icon: 'error' /*아이콘 타입*/
});
} else if (json.email === "false") {
//이미 존재하는 이메일
Swal.fire({
title: 'Fail', /*상단 타이틀*/
text: 'Email is already Exist', /*내용*/
icon: 'error' /*아이콘 타입*/
});
} else {
Swal.fire({
title: 'Fail', /*상단 타이틀*/
text: 'Fail To Register', /*내용*/
icon: 'error'/*아이콘 타입*/
});
}
}
}
});
}
[뷰 타임리프]
name 모델(UserDto)과 맞춰주도록 합니다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="author" content="Kodinger">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>My Login Page — Bootstrap 4 Login Page Snippet</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="/static/css/my-login.css">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
<!-- Optional: include a polyfill for ES6 Promises for IE11 -->
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill"></script>
<!--jquery-->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</head>
<body class="my-login-page">
<section class="h-100">
<div class="container h-100">
<div class="row justify-content-md-center h-100">
<div class="card-wrapper">
<div class="brand">
<img src="/static/img/logo.jpg" alt="bootstrap 4 login page">
</div>
<div class="card fat">
<div class="card-body">
<h4 class="card-title">Register</h4>
<form id="register_form" method="POST"
class="my-login-validation" novalidate="">
<div class="form-group">
<label for="name">Name</label>
<input th:name="name" id="name" type="text" class="form-control" name="name" required
autofocus>
<div class="invalid-feedback">
What's your name?
</div>
</div>
<div class="form-group">
<label for="email">E-Mail Address</label>
<input th:name="email" id="email" type="email" class="form-control" name="email"
required>
<div class="invalid-feedback">
Your email is invalid
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input th:name="password" id="password" type="password" class="form-control"
name="password" required data-eye>
<div class="invalid-feedback">
Password is required
</div>
</div>
<div class="form-group">
<div class="custom-checkbox custom-control">
<input type="checkbox" name="agree" id="agree" class="custom-control-input"
required="">
<label for="agree" class="custom-control-label">I agree to the <a href="#">Terms and
Conditions</a></label>
<div class="invalid-feedback">
You must agree with our Terms and Conditions
</div>
</div>
</div>
<div class="form-group m-0">
<button type="button" onclick="return ajax_register()" id="register_btn"
class="btn btn-primary btn-block">
Register
</button>
</div>
<div class="mt-4 text-center">
Already have an account? <a th:href="@{'/login'}">Login</a>
</div>
</form>
</div>
</div>
<div class="footer">
Copyright © 2020 — ITARTICLE
</div>
</div>
</div>
</div>
</section>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<script src="/static/js/my-login.js"></script>
<script src="/static/js/login/register.js"></script>
</body>
</html>
[화면]
728x90
'웹 > Spring Boot' 카테고리의 다른 글
[Spring Boot] IT Article 토이 프로젝트 (0) | 2020.06.28 |
---|---|
[Spring Boot] 스프링부트 프로젝트 로그인 구현 (AWS -> Naver Cloud 변경) (4) | 2020.06.20 |
[Spring Boot] $.ajax is not a function 에러 처리 (0) | 2020.04.16 |
[Spring Boot] 스프링부트 타임리프 (thymeleaf) 정리 (0) | 2020.04.15 |
[Spring Boot] JPA 추가 및 프로젝트 패키지 분리 (0) | 2020.04.07 |
Comments