Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[com8599-issue6] user 회원가입 기능 #22

Open
wants to merge 13 commits into
base: com8599
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: build

on:
push:
branches: [ main, chance0523, com8599, DolphaGo, hoony-lab, jinyoungchoi95, JunHo-YH, povia, sujl95 , kwj1270 ]
branches: [ main, chance0523, com8599, DolphaGo, hoony-lab, jinyoungchoi95, povia , kwj1270 , ERrorASER ]
pull_request:
branches: [ main, chance0523, com8599, DolphaGo, hoony-lab, jinyoungchoi95, JunHo-YH, povia, sujl95 , kwj1270 ]
branches: [ main, chance0523, com8599, DolphaGo, hoony-lab, jinyoungchoi95, povia , kwj1270 , ERrorASER ]

jobs:
build:
Expand Down
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok:1.18.18'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.7'
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바 객체와 xml을 직렬화/역직렬화 하는 부분이 어디인가요?


//swagger
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
}

apply from: 'test.gradle'
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/study/realworld/RealworldApplication.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.study.realworld;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import java.util.Arrays;
Comment on lines +3 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안 쓰는 import는 지우는 것이 좋습니다.
IntelliJ를 쓰신다면 커밋시에 optimize import에 체크하고 올리시면 됩니다.

스크린샷 2021-08-09 오후 6 19 15

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

피드백감사합니다 다음 커밋부터 유의하여 커밋하겠습니다!!


@SpringBootApplication
public class RealworldApplication {

public static void main(String[] args) {
SpringApplication.run(RealworldApplication.class, args);
}

}
40 changes: 40 additions & 0 deletions src/main/java/com/study/realworld/common/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.study.realworld.common;

public enum ErrorCode {
EXCEPTION(-1, "통신중 에러가 발생했습니다."),
NONE(0, "이상없음"),
INVALID_REQUEST(1, "잘못된 요청입니다."),
DB(2, "데이터 베이스 오류입니다."),
SAME_NICKNAME(3, "동일 닉네임유저가 존재합니다."),
SAME_EMAIL(4, "동일 이메일유저가 존재합니다."),

NOT_FOUND_SESSION_USER(10000, "유저 정보를 찾을 수 없습니다."),

SQLEXCEPTION(-2, "서버와 통신중 에러가 발생했습니다."),
;
Comment on lines +4 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EXCEPTION 이라는 단어만 보고 통신 중 에러가 발생했는지
SQLEXCEPTION이라는 단어만 보고 서버와 통신 중 에러가 발생했는지 추측하기가 어려운데요.

ENUM 명을 NOT_FOUND_SESSION_USER 처럼 구체적으로 작성하는 것이 좋을 것 같습니다.


private int code;
private String desc;

ErrorCode(int code, String desc) {
this.code = code;
this.desc = desc;
}

public int getCode() {
return code;
}

public String getDesc() {
return desc;
}

public static ErrorCode parse(int code) {
for (ErrorCode e : ErrorCode.values()) {
if (code == e.getCode()) {
return e;
}
}
return INVALID_REQUEST;
}
}
34 changes: 34 additions & 0 deletions src/main/java/com/study/realworld/common/JsonFunc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.study.realworld.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class JsonFunc {
public static String getErrorJson(ErrorCode errorCode, Object... objects) {
JsonObject json = new JsonObject();

json.addProperty("E", String.valueOf(errorCode.getCode()));

if (objects == null || objects.length == 0) {
return json.toString();
}

for (int i = 0; i < objects.length; i = i + 2) {
json.addProperty(String.valueOf(objects[i]), String.valueOf(objects[i + 1]));
}
System.out.println(errorCode.name() + " - " + errorCode.getCode() + " - " + errorCode.getDesc());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging이 더 좋을 것 같네요.


return json.toString();
}

public static String getResultJson(Object result) throws JsonProcessingException {
JsonObject json = new JsonObject();

ObjectMapper objectMapper = new ObjectMapper();
json.add("R", new JsonParser().parse(objectMapper.writeValueAsString(result)));

return json.toString();
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/study/realworld/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.study.realworld.controller;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.study.realworld.common.ErrorCode;
import com.study.realworld.common.JsonFunc;
import com.study.realworld.domain.User;
import com.study.realworld.service.UserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class UserController {
UserService userService;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

접근 제어자는 어디에...?


public UserController(UserService userService) {
this.userService = userService;
}
Comment on lines +19 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 방식으로 생성자 주입 하셨다면 위의 UserService는 final로 불변 선언하시면 좋겠네요 :)


@ApiOperation(value = "사용자 등록", notes = "사용자 등록")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동일한 내용을 표현하고 있는데, value와 notes를 구분하신 이유는 무엇인가요?

@PostMapping("/users") //post 등록 api
public String users(@JsonProperty("user") User user) throws JsonProcessingException {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input Parameter로 User를 직접 사용하기 보다는, UserDto 등으로 사용하시는 것이 좋아보입니다. request와 response는 Controller 등의 표현 영역에서 받아 서비스 단에 넘기는 시점에 서비스에 필요한 타입으로 변환해서 넘기고, 받는 것이 좋아요.
나중에 DDD를 공부하시게 된다면 세세하게 아실 수 있을 듯 합니다!

Object result = userService.users(user);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수의 타입에 Object를 사용하는 방식은 좋지 않아 보입니다 ㅜㅜ

if (result instanceof ErrorCode) {
return JsonFunc.getErrorJson((ErrorCode) result);
}
Comment on lines +27 to +29
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 방식으로 에러를 넘기는 것보다는 throw exception을 처리하도록 하시는게 좋아보여요.
Error Handling for REST with Spring
추천드리는 방식으로 개발을 하실 경우, exception을 따로 관리할 수 있기 때문에 운영, 유지보수 측면에서 이점이 상당히 높아집니다^^

return JsonFunc.getResultJson(user);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반환 타입으로 String을 사용하시기 보다는 ResponseEntity를 사용하시는 것이 좋아보입니다.

}
}
76 changes: 76 additions & 0 deletions src/main/java/com/study/realworld/dao/PSSetDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.study.realworld.dao;

import org.springframework.jdbc.core.PreparedStatementSetter;

import java.sql.PreparedStatement;
import java.sql.SQLException;

public class PSSetDao {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserDao에서 드린 의견과 더해 말씀드리면 해당 클래스는 사용하지 않게 될 확률이 높아 제거하셔도 무방할 것으로 보입니다.

public static class PSSForInts implements PreparedStatementSetter {
private Integer[] value;

public PSSForInts(Integer... value) {
this.value = value;
}

public void setValues(PreparedStatement ps) throws SQLException {

for (int i = 0; i < value.length; i++) {
ps.setInt((i + 1), this.value[i]);
}
}
}

public static class PSSForStrings implements PreparedStatementSetter {
private String[] value;

public PSSForStrings(String... value) {
this.value = value;
}

public void setValues(PreparedStatement ps) throws SQLException {

for (int i = 0; i < value.length; i++) {
ps.setString((i + 1), this.value[i]);
}
}
}

public static class PSSForIntsStrings implements PreparedStatementSetter {
int intCount;
int stringCount;
Object[] objects;

public PSSForIntsStrings(int intCount, int stringCount, Object... objects) {
this.intCount = intCount;
this.stringCount = stringCount;
this.objects = objects;
}

public void setValues(PreparedStatement ps) throws SQLException {
int pos = 1;

for (int i = 0; i < intCount; i++) ps.setInt(pos++, (Integer) objects[i]);
for (int i = 0; i < stringCount; i++) ps.setString(pos++, (String) objects[i + intCount]);
}
}

public static class PSSForStringsInts implements PreparedStatementSetter {
int stringCount;
int intCount;
Object[] objects;

public PSSForStringsInts(int stringCount, int intCount, Object... objects) {
this.stringCount = stringCount;
this.intCount = intCount;
this.objects = objects;
}

public void setValues(PreparedStatement ps) throws SQLException {
int pos = 1;

for (int i = 0; i < stringCount; i++) ps.setString(pos++, (String) objects[i]);
for (int i = 0; i < intCount; i++) ps.setInt(pos++, (Integer) objects[i + stringCount]);
}
}
}