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

[게시판 회원 기능] 베디 미션 제출 합니다. #63

Merged
merged 67 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
21df515
remove : 기존 로직 삭제
vsh123 Jul 16, 2019
52f4012
feat : MainController 구현
vsh123 Jul 16, 2019
2159261
feat: Article 구현
vsh123 Jul 16, 2019
2fb0c09
feat: ArticleReposiory 구현
vsh123 Jul 16, 2019
95fd8d0
feat: ArticleController.write()
vsh123 Jul 16, 2019
1cad0c7
feat: ArticleController.show()
vsh123 Jul 16, 2019
44dc298
feat: ArticleController.editForm()
vsh123 Jul 16, 2019
a9fda55
ArticleController.edit()
vsh123 Jul 16, 2019
0386658
feat: ArticleController.delete()
vsh123 Jul 16, 2019
0b5b1bd
feat: ArticleController.writeForm()
vsh123 Jul 16, 2019
cd21f32
rename: ArticleControllerTests
vsh123 Jul 16, 2019
821ecce
feat: MainController Aritcles 조회
vsh123 Jul 16, 2019
908ed88
refactor: @transactional 추가
vsh123 Jul 17, 2019
7d3a682
rename: template 이름 변경
vsh123 Jul 17, 2019
49bf7b7
feat: UserController.signupForm()
vsh123 Jul 17, 2019
c0ee6a0
feat: 회원가입 유효성 검사
vsh123 Jul 17, 2019
38a5156
feat: 회원가입 이메일 중복, 패스워드 중복 검사
vsh123 Jul 17, 2019
946b966
feat: 회원가입 프론트 구현
vsh123 Jul 17, 2019
85d66f2
feat: 로그인 구현
vsh123 Jul 17, 2019
24d9d5f
feat: login 구현
vsh123 Jul 17, 2019
eff17e5
feat: 로그아웃
vsh123 Jul 17, 2019
8e92b91
feat: 회원 목록 조회
vsh123 Jul 18, 2019
5924c54
feat: 마이페이지, 수정폼 구현
vsh123 Jul 18, 2019
c5f9692
feat: 회원정보 수정
vsh123 Jul 18, 2019
d98f66c
feat: 회원탈퇴
vsh123 Jul 18, 2019
a7d29a4
refactor: UserDto
vsh123 Jul 18, 2019
724fc14
refactor: 테스트코드 중복제거
vsh123 Jul 18, 2019
39d11f7
feat: interceptor
vsh123 Jul 18, 2019
9fafd01
feat: logger 추가
dpudpu Jul 19, 2019
07aa7d2
test: LoginInterceptor 세션 테스트 추가
dpudpu Jul 19, 2019
da27b3f
feat: jupiter-params 추가
dpudpu Jul 19, 2019
f8eaf0f
refactor: html 중복 제거
dpudpu Jul 19, 2019
0d41c3c
feat: Articles Paging 구현
dpudpu Jul 19, 2019
64c43a4
test: UserControllerTest 세션 테스트 추가
dpudpu Jul 20, 2019
de6c1c0
refactor: uri 상수 처리
dpudpu Jul 20, 2019
ee00f77
test: UserServiceTest
dpudpu Jul 20, 2019
f5d62fa
style: 포맷팅
dpudpu Jul 20, 2019
81b5335
refactor: 샘플데이터 수정
dpudpu Jul 20, 2019
8ff0ca3
refactor: user session 상수 처리
dpudpu Jul 20, 2019
39ae181
rename: ValidSignupException -> ValidUserException
dpudpu Jul 20, 2019
5502bff
refactor: LoginInterceptor 매직넘버 상수처리
dpudpu Jul 21, 2019
80d6306
fix: logout AuthInterceptor에서 튕기는 문제 해결
dpudpu Jul 21, 2019
654fd03
style: build.gradle 정리
dpudpu Jul 21, 2019
1fc5673
refactor: errorAttributes() 를 ErrorConfig.class 로 분리
dpudpu Jul 21, 2019
296c66f
refactor: uri 상수 제거
dpudpu Jul 21, 2019
fe563ad
refactor: Article.update() 수정
dpudpu Jul 21, 2019
8db3f71
refactor: test 코드 필요 없는 어노테이션 제거
dpudpu Jul 21, 2019
28a1191
refactor: 인터셉터 클래스 commons 패키지에서 interceptor 로 변경
dpudpu Jul 21, 2019
86143aa
refactor: BeanUtils 제거, User setter 제거
dpudpu Jul 21, 2019
1a9bcb1
refactor: MainController.index Pageable 파라미터로 변경
dpudpu Jul 21, 2019
ff6f559
feat: User.authenticate 추가
dpudpu Jul 21, 2019
95d4f77
refactor: ControllerTests 에서 service 빈 제거하고 api를 직접 호출하는 방식으로 변경
dpudpu Jul 22, 2019
c5c801e
refactor: user session 처리용 UserSession 생성
dpudpu Jul 22, 2019
5c27961
style: 포맷팅
dpudpu Jul 22, 2019
fbf4518
feat: User 유효성검사 추가
dpudpu Jul 22, 2019
edf822e
refactor: Article @Builder 방식 변경
dpudpu Jul 22, 2019
864ba07
fix: LoginInterceptor 적용 패스 및 테스트코드 추가
dpudpu Jul 22, 2019
53bf60c
fix: UserDto.Update.toUser()
dpudpu Jul 22, 2019
9e31983
fix: test코드 session 추가
dpudpu Jul 22, 2019
bbe330e
docs: application.properties spring.jpa.show-sql=true 제거
dpudpu Jul 22, 2019
56e0055
refactor: UserDto.Update.toUser() 방식 수정
dpudpu Jul 22, 2019
09a288b
refactor: UserDto.Update에 id 필드 추가
dpudpu Jul 23, 2019
dde12ec
refactor: User unique 설정 방식 변경
dpudpu Jul 23, 2019
945cb29
refactor: SessionId 상수 UserSession 으로 이동
dpudpu Jul 23, 2019
3c6c1ba
refactor: UserService.login() UserSession 반환 하는 부분 수정
dpudpu Jul 23, 2019
13c0e9e
feat: UserSessionArgumentResolver
dpudpu Jul 23, 2019
3fd3101
refactor: Entity 기본생성자 private으로 변경
dpudpu Jul 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'java'
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'java'
}

apply plugin: 'io.spring.dependency-management'
Expand All @@ -10,17 +10,24 @@ version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
runtimeOnly('org.springframework.boot:spring-boot-devtools')
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'junit'
}
testImplementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
implementation 'org.projectlombok:lombok:1.18.8'

annotationProcessor 'org.projectlombok:lombok:1.18.8'

runtimeOnly 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'

testImplementation "org.junit.jupiter:junit-jupiter-params:5.4.2"
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-starter-webflux'
}
20 changes: 0 additions & 20 deletions src/main/java/techcourse/myblog/HelloWorldController.java

This file was deleted.

1 change: 0 additions & 1 deletion src/main/java/techcourse/myblog/MyblogApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ public class MyblogApplication {
public static void main(String[] args) {
SpringApplication.run(MyblogApplication.class, args);
}

}
54 changes: 54 additions & 0 deletions src/main/java/techcourse/myblog/articles/Article.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package techcourse.myblog.articles;

import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Getter
@Setter

Choose a reason for hiding this comment

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

setter는 제거해보아요

Copy link
Author

@dpudpu dpudpu Jul 21, 2019

Choose a reason for hiding this comment

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

여기서 Setter를 사용한 이유는 �컨트롤러에서 파라미터로 받기 위해서 입니다.
public String write(Article article) {
setter를 없애려면 dto를 만들어야 하는데 현재는 dto를가 필요 없다고 판단해서 이렇게 했습니다.
setter를 제거하고 dto를 만드는 것이 좋을까요?

Choose a reason for hiding this comment

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

지금 과정에서는 dto 추가하지말고 지금 구조로 가시죠!

@ToString

Choose a reason for hiding this comment

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

toString도 쓰는 곳이 없으면 제거해보아요

Copy link
Author

@dpudpu dpudpu Jul 21, 2019

Choose a reason for hiding this comment

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

사실 지금 상황에서는 사용할 일이 없지만
이펙티브자바 아이템 12. toString을 항상 재정의하라를 읽었는데
디버깅, 로깅이 편해지지지만 그 외에도 직접 호출하지 않더라도 다른 어딘가에서 사용될 수 있다. 라는 문구가 있더라고요. 혹시 toString 을 제거해야 할 이유가 따로 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

자답 : jpa 공부중인데 양방향 관계시에 toString()을 잘 못 사용하면 무한루프가 발생할 수 있다는군요.

Choose a reason for hiding this comment

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

넵 맞습니다 ㅎㅎ;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@EqualsAndHashCode(of = "id")
public class Article {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column
private String title;

@Column
private String contents;

@Column
private String coverUrl;

@CreatedDate
@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", updatable = false)
private LocalDateTime regDate;

@LastModifiedDate
@Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime updateDate;

@Builder
private Article(final String title, final String contents, final String coverUrl) {
this.title = title;
this.contents = contents;
this.coverUrl = coverUrl;
}

public void update(Article other) {
this.updateDate = LocalDateTime.now();
this.title = other.title;
this.coverUrl = other.coverUrl;
this.contents = other.contents;
}
}


51 changes: 51 additions & 0 deletions src/main/java/techcourse/myblog/articles/ArticleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package techcourse.myblog.articles;


import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/articles")
@RequiredArgsConstructor
public class ArticleController {
private final ArticleService articleService;

@GetMapping("/new")
public String writeForm() {
return "article-edit";
}

@PostMapping
public String write(Article article) {
Article savedArticle = articleService.save(article);
return "redirect:/articles/" + savedArticle.getId();
}

@GetMapping("/{id}")
public String show(@PathVariable Long id, Model model) {
Article article = articleService.findById(id);
model.addAttribute(article);
return "article";
}

@GetMapping("/{id}/edit")
public String editForm(@PathVariable Long id, Model model) {
Article article = articleService.findById(id);
model.addAttribute(article);
return "article-edit";
}

@PutMapping("/{id}")
public String edit(Article editedArticle) {
Article article = articleService.edit(editedArticle);
return "redirect:/articles/" + article.getId();
}

@DeleteMapping("/{id}")
public String delete(@PathVariable Long id) {
articleService.deleteById(id);
return "redirect:/";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package techcourse.myblog.articles;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ArticleRepository extends JpaRepository<Article, Long> {

}
41 changes: 41 additions & 0 deletions src/main/java/techcourse/myblog/articles/ArticleService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package techcourse.myblog.articles;

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RequiredArgsConstructor
public class ArticleService {
private final ArticleRepository articleRepository;

public Article save(Article article) {
return articleRepository.save(article);
}

@Transactional(readOnly = true)
public Article findById(Long id) {
return articleRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Can't find Article : " + id));
}

public Article edit(Article editedArticle) {
Article article = findById(editedArticle.getId());

article.update(editedArticle);

return article;
}

public void deleteById(Long id) {
articleRepository.deleteById(id);
}

@Transactional(readOnly = true)
public Page<Article> findAll(Pageable pageable) {
return articleRepository.findAll(pageable);
}
}
29 changes: 29 additions & 0 deletions src/main/java/techcourse/myblog/config/ErrorConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package techcourse.myblog.config;

import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.WebRequest;
import techcourse.myblog.users.ValidUserException;

import java.util.Map;

@Configuration
public class ErrorConfig {
@Bean
public ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {

@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
Throwable error = getError(webRequest);
if (error instanceof ValidUserException) {
errorAttributes.put("errors", ((ValidUserException) error).getErrors());
}
return errorAttributes;
}
};
}
}
39 changes: 39 additions & 0 deletions src/main/java/techcourse/myblog/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package techcourse.myblog.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import techcourse.myblog.interceptor.AuthInterceptor;
import techcourse.myblog.interceptor.LoginInterceptor;
import techcourse.myblog.users.UserSessionArgumentResolver;

import java.util.List;


@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

private final LoginInterceptor loginInterceptor;
private final AuthInterceptor authInterceptor;
private final UserSessionArgumentResolver userSessionArgumentResolver;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/users")
.addPathPatterns("/users/**");

registry.addInterceptor(authInterceptor)
.addPathPatterns("/users/{id}")
.addPathPatterns("/users/{id}/edit")
.excludePathPatterns("/users/logout");
}

@Override
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userSessionArgumentResolver);
}
}
68 changes: 0 additions & 68 deletions src/main/java/techcourse/myblog/domain/Article.java

This file was deleted.

Loading