| HTTP 요청/응답 사항
POST /member/register
파라미터 : 이메일, 비밀번호, 이름, 전화번호
정책 :
- 프론트 :
이메일, 비밀번호, 이름, 전화번호 필수 정보가 입력되지 않은 경우,
이메일 형식이 맞지 않는 경우, 비밀번호 규칙이 다른 경우, 비밀번호 확인이 틀린 경우 체크
- 백엔드 :
동일한 아이디가 있는 경우, 실패 응답
[가입하기] 터치 후, 작성한 이메일로 메일 인증
성공 응답 : login-complete.html
- Member 테이블
* 아래를 보면 jpa에 의해 db에 저장되는 방식이 camel -> snake로 변환되는 걸 볼 수 있다.
db | html(parameter) / spring | |
이메일 | user_id | userId |
이름 | user_name | userName |
휴대폰번호 | phone_number | phoneNumber |
비밀번호 | password | password |
가입일 | registered_at | registeredAt |
수정일 | updated_at | updatedAt |
- request
POST http://localhost:8080/member/register
Content-Type: application/json
{
"userId" : "test@gmail.com",
"password" : "abcdEF123!@#",
"userName" : "테스트",
"phoneNumber" : "010-7777-8888"
}
[ ERD ]
- 디자인패턴 : 아래와 같이 작업 예정
| 새롭게 배운 내용들
1. 클라이언트단 구성
- HTML form : input의 name을 통해 parameter를 지정하고, input[type=submit] 또는 button을 통해 submit()을 한다.
<form method = "post">
<input type = "text" name = "userId">
<input type = "submit" value = "제출">
<!-- <button onclick = "return this.form.submit()">제출</button> -->
</form>
- <! 주의사항> 클라이언트에서 submit 시 인코딩 방식
: 인코딩 방식을 x-www-form-urlencoded로 보내게 되면 spring의 @RequestBody로 인식을 하지 못한다.
: 왜냐하면 @RequestBody는 Json 타입을 받기 때문에, 이럴 경우 @RequestBody 없이 작성해주는게 필요하다.
form 인코딩 타입 | 사용기술 | 내용 |
x-www-form-urlencoded | 일반 form | 단순 submit을 하게 되면 key=value&key=value 형태로 데이터 전송 |
json | ajax | ajax를 통해서 인코딩 타입을 지정해서 보낼 경우 |
// 만약, 현장에서 html의 request 타입이 어떻게 오는지 지정해두지 않은 상태라면
// 메소드를 overloading하여 핸들러가 알아서 메소드를 찾을 수 있도록 해주어야한다.
@PostMapping(value = "/member/register", consumes = MediaType.APPLICATION_JSON_VALUE)
public String registerSubmit(@RequestBody MemberRegister.Request request) {
// 처리
return "member/register_complete";
}
@PostMapping(value = "/member/register", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String registerSubmit(MemberRegister.Request request) {
// 처리
return "member/register_complete";
}
2. JPA를 통한 DB 저장
(1) JDBC를 통해 DB연결, ORM (JPA) 의존성 주입 및 환경 설정
1) pom.yml 에 depencendy 추가 : JDBC driver, jpa 라이브러리
// jdbc
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
// jpa
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2) application.yml에 DB접속정보, JPA환경 설정
- DB 접속정보를 알고 싶다면, 인텔리J의 [database] 탭에서 먼저 접속을 시도해보자.
> url 정보를 복사해서 가져올 수 있도록 되어 있다.
spring:
datasource:
url: jdbc:mariadb://
driver-class-name:
username:
password:
jpa:
generate-ddl: true // 내장 ddl로 테이블 자동생성
hibernate:
ddl-auto: update // update를 자동적용
open-in-view: true
properties:
hibernate:
format_sql: true
show_sql: true
(2) Entity 도메인 클래스 생성, repository 생성
- Entity (= domain) : @Entity를 통해 만든다.
- @Entity를 추가한 클래스가 로드되면 아래와 같이 table이 자동 생성된다.
3. 서비스 및 컨트롤러 작업 - 새로 배운 내용만 정리
(1) Thymeleaf 사용하여 Data-binding하기
- 컨트롤러에서 Model 객체를 사용하여, 전송할 html에 data-binding을 할 수 있다.
// Model 객체를 통해 Databinding : addAttribute("parameter", "value")
@PostMapping(value = "/member/register", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String registerSubmit(MemberRegister.Request request, Model model) {
boolean result = memberService.register(request);
model.addAttribute("result", result); // model을 통해 Data binding
return "member/register_complete";
}
- 이동할 뷰단에서 thymeleaf 사용하기
* JSP의 JSTL과 거의 비슷한 구조를 보인다.
* 자세한 thymeleaf 사용 방법 : https://velog.io/@alicesykim95/Thymeleaf
// 뷰단에 namespace 추가
<html xmlns:th="http://www.thymeleaf.org">
// thymeleaf 사용법
<p th:if="${result}">
<p th:if="${result eq false}">
4. 구글 gmail로 인증 메일 보내기
(1) pom.xml에 Java Mail Starter 라이브러리 추가
// Java Mail Starter 라이브러리 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
(2) 구글 계정/ gmail 설정
1) [google 계정 관리]-[보안]에서 2단계 인증 사용
2) 인증키 받기 : 1) 과 동일한 위치에서 [앱 비벌번호] 발급
3) gmail 설정 - [모든 설정 보기] 에서 아래 사항 체크
가. POP가 사용 설정되어 있습니다.
나. IMAP가 사용할 수 있습니다.
(3) application.yml에서 설정하기
* gmail 포트는 587이 보통임
// 필수 설정
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.protocol = smtp
spring.mail.username = gmail account
spring.mail.password = password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
// 추가 설정
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
spring
mail:
host: smtp.gmail.com
port: 587
username: //email
password: //인증키
properties:
mail:
smtp:
auth: true
ssl:
trust: smtp.gmail.com
starttls:
enable: true
(4) SMTP 메일 전송을 위한 컴포넌트 클래스 생성
- Java에서 SMTP프로토콜을 통해 메일 전송을 하기 위해서는 JavaMailSender를 사용해야한다.
- JavaMailSender는 아래와 같이 send()라는 메소드를 가지고 있는데, 이 send() 안에는 어떤 메세지를 메일에 담을 것인지를 약속된 객체 포맷으로 담아주어야한다.
- 대체적으로 MimeMessagePreparator를 통해서 메일 내용을 작성한다고 한다.
클래스 | JavaMailSender | MimeMessageHelper/SimpleMaileMessage |
메소드 | send(SimpleMailMessage msg) send(MimeMessagePreparator msg) |
setTo(String email) setSubject(String subject) setText(String text) |
- 수업 시간에 사용했던 코드 (*.. 동일한 코드라서, 혹시 저작권 이슈 있다면 댓글 주시면 삭제하겠습니다.)
@Component
@RequiredArgsConstructor
public class MailComponents {
// 1. JavaMailSender 생성자에 추가
private final JavaMailSender javaMailSender;
public boolean sendMail(String mail, String subject, String text) {
boolean result = false;
// 2. MimeMessagePreparator의 prepare() 함수를 익명클래스로 overriding
MimeMessagePreparator msg = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
mimeMessageHelper.setTo(mail);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(text, true); // true -- html포함가능
}
};
// 3. JavaMailSender의 send()로 전송
try {
javaMailSender.send(msg);
result = true;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return result;
}
}
- 아래와 같이 generate-ddl과 ddl-auto가 update로 되어 있다면 테이블에 칼럼이 정상적으로 추가된다.
jpa:
generate-ddl: true
hibernate:
ddl-auto: update
show-sql: true
| 정리
✅ 클라이언트에서 POST로 데이터(=content)를 보낼 때, ContentType을 지정해주어야한다. * 지정하지 않으면, 디폴트로 x-www-form-urlencoded로 key=value&key=value 형태로 전달된다. * 만약 Content-type을 지정하기 어려운 상황이라면, Controller의 PostMapping 메소드에 consumes로 overloading한다. @PostMapping(value = "/member/register", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) ✅ x-www-form-urlencoded으로 POST한 경우라면, 컨트롤러에서 받을 때엔 단순 객체 타입을 사용하며, json으로 POST한 경우라면, 컨트롤러에서 받을 때에 @RequestBody를 사용한다. * 현장에서는 ajax를 통해 content-type을 json으로 지정해 보내는 걸 선호한다고 한다. ✅ DB/JDBC/ORM(JPA) 연결하기 (1) dependency에 jdbc와 orm(jpa) 라이브러리를 추가하며 (2) application.yml에 datasource와 jpa 설정을 작성한다. * @Entity가 포함된 클래스를 jpa가 읽어 db에 올려준다. * 만약 @EntityListener를 추가한 경우라면, 별도의 ListerConfig클래스에 @Configuration @EnableJpaAuditing과 같이 설정 클래스를 DI에 추가해주어야한다. ✅ Thymeleaf을 통해 Data-binding을 할 수 있다. (1) 컨트롤러의 메소드 매개변수에 Model 객체를 포함한다. (2) Model 객체의 addAttribude()를 통해 Data-binding을 하고 (3) Thyemleaf 링크를 html namespace에 추가하고, 해당 문법을 사용해 parameter에서 attribute를 읽어온다. ✅ 구글 gmail로 인증 메일을 보내기 위한 사전 작업 (1) 구글 계정의 [보안] 에서 [2단계 인증]을 "사용"으로 표시한다. (2) 구글 계정의 [보안] 에서 [앱 비빌번호]를 생성한다. ---> 인증키로 사용 ✅ Application 내에서 SMTP 메일 전송하기 (1) dependency에 java mail starter 라이브러리를 추가한다. (2) application.yml에서 mail의 host/port/username/password를 설정하고, properties내부에 smtp 설정을 한다. (3) 별도의 components 클래스에 메일 전송 메소드를 생성한다. 가. JavaMailSender의 send() 안에 넣을 메세지 내용을 MimeMessagePreparator를 익명클래스로 구현하고, 나. 예외처리와 함께 send()한다. (4) 클라이언트 회원가입 폼에서 계정 생성을 POST로 요청할 때(ex.POST member/register) (3)에서 만든 메소드를 호출하여 메세지를 전송한다. * UUID.randomUUID().toString().replace("-","")를 통해 DB에 Auth key도 생성했다. (5) 사용자가 본인 이메일에 있는 링크를 통해 예를들어 GET방식으로 쿼리스트링(ex. authKey="weroiwpt")을 날리면, 해당 쿼리스트링에 따라 별도의 컨트롤러에서 DB의 인증상태를 업데이트 한다. |
[ 참고 및 출처 ]
부트캠프 수업 내용 정리
spring post 요청과 content-type https://blog.naver.com/PostView.naver?blogId=writer0713&logNo=221853596497&redirect=Dlog&widgetTypeCall=true&directAccess=false
https://stackoverflow.com/questions/16115453/javamail-could-not-convert-socket-to-tls-gmail/20773077
'Framework > 프로젝트로 스프링 이해하기' 카테고리의 다른 글
[LMS 만들기] 비밀번호 초기화 요청 및 메일 링크를 통한 초기화 (1) | 2022.10.04 |
---|---|
[LMS 만들기] 스프링 시큐러티를 이용한 로그인/로그아웃 (0) | 2022.10.03 |
[LMS 만들기] 스프링 컨트롤과 주소 매핑 (0) | 2022.09.30 |
[LSM 만들기] Maven 프로젝트 환경 보기 (0) | 2022.09.29 |
[LSM 만들기] 스프링부트 프로젝트 생성하기 (0) | 2022.09.28 |