-
Notifications
You must be signed in to change notification settings - Fork 28
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
[Starve + Kyu] Mission5 - XHR과 AJAX #138
base: Jiwon-JJW
Are you sure you want to change the base?
Changes from all commits
64fafeb
6127c2b
74ecf55
c87abb7
881f2a7
4ddc5e9
380bc10
c28b42f
05e5730
c2a3756
7b035e0
8eea4dd
e92d559
3a9a643
9bfddb9
e496d96
79d66bd
1639277
f77f441
2674f9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,13 @@ dependencies { | |
implementation group: 'com.h2database', name: 'h2', version: '1.4.200' | ||
runtimeOnly 'com.h2database:h2' | ||
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' | ||
|
||
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2' | ||
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2' | ||
|
||
testImplementation('org.springframework.boot:spring-boot-starter-test') { | ||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' | ||
} | ||
Comment on lines
+30
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spring Boot 2.4 버전부터는 vintage engine이 기본적으로 포함되어있지 않아서 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리고 위에 이미 존재합니다. |
||
} | ||
|
||
test { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.codessquad.qna; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import springfox.documentation.builders.ApiInfoBuilder; | ||
import springfox.documentation.builders.PathSelectors; | ||
import springfox.documentation.builders.RequestHandlerSelectors; | ||
import springfox.documentation.service.ApiInfo; | ||
import springfox.documentation.service.Contact; | ||
import springfox.documentation.spi.DocumentationType; | ||
import springfox.documentation.spring.web.plugins.Docket; | ||
import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
|
||
import java.util.ArrayList; | ||
|
||
@Configuration | ||
@EnableSwagger2 | ||
public class SwaggerConfig { | ||
|
||
@Bean | ||
public Docket apiV2() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 왜 v2인가요? |
||
return new Docket(DocumentationType.SWAGGER_2) | ||
.groupName("greetings") | ||
.apiInfo(apiInfo()) | ||
.select() | ||
.paths(PathSelectors.ant("/api/**")) | ||
.build(); | ||
|
||
} | ||
|
||
private ApiInfo apiInfo() { | ||
return new ApiInfoBuilder() | ||
.title("Spring REST Sample with Swagger") | ||
.description("Spring REST Sample with Swagger") | ||
.termsOfServiceUrl("http://www-03.ibm.com/software/sla/sladb.nsf/sla/bm?Open") | ||
.license("Apache License Version 2.0") | ||
.licenseUrl("https://github.com/IBM-Bluemix/news-aggregator/blob/master/LICENSE") | ||
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 라이선스까지 있군요? |
||
.version("2.0") | ||
.build(); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 통행금지 표시가 있네요! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.codessquad.qna.domain; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import org.springframework.data.annotation.CreatedDate; | ||
import org.springframework.data.annotation.LastModifiedDate; | ||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Objects; | ||
|
||
@MappedSuperclass | ||
@EntityListeners(AuditingEntityListener.class) | ||
public class AbstractEntity { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Abstract라는 키워드를 적어주기보다는 저는 Base를 선호합니다~ |
||
private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@JsonProperty | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JsonProperty를 따로 붙여주신 이유가 있나요? |
||
private Long id; | ||
|
||
@CreatedDate | ||
private LocalDateTime createDate; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터 형식은 LocalDateTime이므로 createDateTime으로 만들어주시는 것을 추천합니다. |
||
|
||
@LastModifiedDate | ||
private LocalDateTime modifiedDate; | ||
|
||
private boolean deleted; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 모든 DB 컬럼들이 softdelete로 구현되는건가요? |
||
|
||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getFormattedDateTime() { | ||
return getFormattedDate(createDate); | ||
} | ||
|
||
public String getFormattedModifiedDate() { | ||
return getFormattedDate(modifiedDate); | ||
} | ||
|
||
public String getFormattedDate(LocalDateTime dateTime) { | ||
return dateTime.format(DATE_TIME_FORMAT); | ||
} | ||
Comment on lines
+36
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기 네이밍도 위의 피드백과 함께 고쳐주세요~ |
||
|
||
|
||
public boolean isMatchingId(long id) { | ||
return this.id == id; | ||
} | ||
|
||
public void deleted() { | ||
this.deleted = true; | ||
} | ||
Comment on lines
+53
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete가 맞겠죠? |
||
|
||
public boolean isDeleted() { | ||
return this.deleted; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
AbstractEntity that = (AbstractEntity) o; | ||
return Objects.equals(id, that.id); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id); | ||
} | ||
Comment on lines
+61
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자... 잘 생각해봅시다. |
||
|
||
@Override | ||
public String toString() { | ||
return "AbstractEntity{" + | ||
"id=" + id + | ||
", createDate=" + createDate + | ||
", modifiedDate=" + modifiedDate + | ||
'}'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,80 @@ | ||
package com.codessquad.qna.domain; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@Entity | ||
public class Question { | ||
private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
public class Question extends AbstractEntity { | ||
|
||
@ManyToOne | ||
@JsonProperty | ||
@JoinColumn(foreignKey = @ForeignKey(name = "fk_question_writer")) | ||
private User writer; | ||
|
||
@JsonProperty | ||
private String title; | ||
|
||
@OneToMany(mappedBy = "question") | ||
@OrderBy("id ASC") | ||
private List<Answer> answers; | ||
private List<Answer> answers = new ArrayList<>(); | ||
|
||
@Lob | ||
@JsonProperty | ||
private String contents; | ||
private LocalDateTime createdDateTime = LocalDateTime.now(); | ||
|
||
private boolean deleted; | ||
@JsonProperty | ||
private int answerCount = 0; | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
public Question() { | ||
|
||
public User getWriter() { | ||
return writer; | ||
} | ||
|
||
public void setWriter(User writer) { | ||
public Question(User writer, String title, String contents) { | ||
this.writer = writer; | ||
} | ||
|
||
public String getTitle() { | ||
return title; | ||
} | ||
|
||
public void setTitle(String title) { | ||
this.title = title; | ||
} | ||
|
||
public String getContents() { | ||
return contents; | ||
} | ||
|
||
public void setContents(String contents) { | ||
this.contents = contents; | ||
} | ||
|
||
public LocalDateTime getCreatedDateTime() { | ||
return createdDateTime; | ||
} | ||
|
||
public String getFormattedDateTime() { | ||
return createdDateTime.format(DATE_TIME_FORMAT); | ||
} | ||
|
||
public List<Answer> getAnswers() { | ||
return answers; | ||
public boolean isMatchingWriter(User loginUser) { | ||
return this.writer.equals(loginUser); | ||
} | ||
|
||
public void delete() { | ||
this.deleted = true; | ||
public void update(String updateTitle, String updateContents) { | ||
this.title = updateTitle; | ||
this.contents = updateContents; | ||
} | ||
|
||
public void addAnswer(Answer answer) { | ||
answers.add(answer); | ||
answerCount++; | ||
} | ||
|
||
public boolean isMatchingWriter(User loginUser) { | ||
return this.writer.equals(loginUser); | ||
public void deleteAnswer(Answer answer) { | ||
if (answers.contains(answer)) { | ||
answer.deleted(); | ||
answerCount--; | ||
} | ||
} | ||
Comment on lines
52
to
62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 강의를 따라하신 거겠죠? |
||
|
||
public void update(Question updateQuestion) { | ||
this.title = updateQuestion.title; | ||
this.contents = updateQuestion.contents; | ||
public List<Answer> getAnswers() { | ||
return answers.stream() | ||
.filter(answer -> !answer.isDeleted()) | ||
.collect(Collectors.toList()); | ||
Comment on lines
+64
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 처음 가져올 때, answers가 필터링 되어서 가져와지는게 좋겠죠? |
||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Qna{" + | ||
super.toString() + | ||
"writer='" + writer + '\'' + | ||
", title='" + title + '\'' + | ||
", contents='" + contents + '\'' + | ||
'}'; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swagger를 사용하는 이유를 한 번 생각해보세요!