24년 여름방학
이번 여름방학때는 백엔드에 집중했었습니다. 처음에는 기본적인 흐름을 숙달하기 위해 CRUD게시판을 여러번 만들어보면서 스프링에 어느정도 익숙해졌고, 시큐리티 적용과 api호출 등 점차 기능을 추가해보았습니다.
곧 개강을 앞둔 이 시점에서, 여름방학 때 진행한 프로젝트들에서 사용했던 기술과 어떻게 사용했는지를 정리해보려고 합니다.
먼저 사용했던 기술스택입니다.
1. Backend
- Java
- Spring Boot
- Spring MVC
- Spring Data JPA
- Spring Security
- Validation
2. Frontend
- Thymeleaf
- HTML/CSS/JavaScript
- Thymeleaf Extras Spring Security
3. Database
- MySQL
- JPA/Hibernate
4. Build Tools
- Gradle
5. Testing
- JUnit
- Mockito
6. 기타
- figma
- Lombok
- Git/GitHub
- google maps api
진행했던 프로젝트는 총 3개이며, 다음과 같습니다.
1 : CRUD게시판
깃허브 링크
기본적인 CRUD기능이 있는 게시판입니다.
- 게시글
- 검색
- 작성
- 수정
- 삭제
- api
- 토지 매매 신고 조회
- 토지 매매 신고 조회
회원서비스 구현을 하지 않았고, 게시글 수정 및 삭제는 게시글 작성시 입력한 비밀번호를 통해 이뤄지도록 구현했습니다.
//게시글 삭제
@PostMapping("/post/delete/{id}")
public String deletePost(@PathVariable("id")Long id, PasswordForm form, Model model)
{
if(postService.checkPassword(id, form.getPassword()))
{
postService.deletePost(id);
}
return "redirect:/posts";
}
//게시글 수정폼 이동
@GetMapping("/post/update/{id}")
public String updatePost(@PathVariable("id")Long id, Model model)
{
Post post = postService.onePost(id).get();
model.addAttribute("post",post);
return "posts/updatePostForm";
}
//수정내용 및 비밀번호 처리
@PostMapping("/post/update/{id}")
public String updatePost2(@PathVariable("id")Long id, UpdateForm form)
{
if (postService.checkPassword(id, form.getPassword()))
{
postService.updatePost(id, form.getTitle(), form.getContent());
}
return "redirect:/posts";
}
추가로 구현한 것
깃헙에 푸시는 안되어있지만, 공공데이터 포탈의 api로 데이터를 처리해보았습니다.
국토교통부_토지 매매 신고 조회 서비스 api로 ‘지역 및 년월’을 요청하여 xml을 응답으로 받았습니다.
받은 xml을 서버에서 파싱해 데이터를 가공한 뒤, 웹에 보여주도록 만들었습니다.
2 : Spring Security를 적용한 CRUD게시판
깃허브 링크
스프링 시큐리티를 적용해본 게시판입니다.
-
회원서비스
- 회원가입
- 로그인/아웃
-
게시글
- 작성
- 수정
- 삭제
-
댓글
- 작성
- 수정
- 삭제
사진과 같이, 본인이 작성한 게시글 및 댓글에 수정/삭제 기능이 표시됩니다.
Principal 객체를 이용해, 요청을 보낸 사용자의 관리자 | 작성자 여부를 클라이언트로 함께 반환합니다.
@GetMapping("post/{id}")
public String postDetail(@PathVariable Long id, Model model, Principal principal)
{
PostResponse postResponse = postService.findById(id);
model.addAttribute("post",postResponse);
boolean isAuthor = memberService.isAuthor(principal, postResponse);
boolean isAdmin = memberService.isAdmin(principal);
String currentId;
if(principal != null) {currentId = principal.getName();}
else {currentId = null;}
model.addAttribute("isAuthor", isAuthor);
model.addAttribute("isAdmin", isAdmin);
model.addAttribute("currentId",currentId);
// 플래시 속성을 가져와서 모델에 추가
if (model.containsAttribute("modifyComment")) {
model.addAttribute("modifyComment", model.getAttribute("modifyComment"));
}
return "Board/postDetail";
}
댓글 수정기능에서는 redirectAttributes.addFlashAttribute()를 통해 리다이렉트시에도 데이터가 유지될 수 있도록 하였습니다.
클라이언트에서 댓글 수정을 요청하면, 컨트롤러에서 해당 댓글의 id를 리다이렉트 시에도 유지되도록 하여 현재 화면을 리다이렉트하며, 다음과 같이 수정 입력란이 생성되게 하였습니다.
@GetMapping("post/{post_id}/comment/{comment_id}/modify")
public String commentModify(@PathVariable Long post_id, @PathVariable Long comment_id, Principal principal, RedirectAttributes redirectAttributes)
{
//사용자 검열구현
//...
redirectAttributes.addFlashAttribute("modifyComment", comment_id);
return "redirect:/post/"+post_id;
}
스프링 시큐리티를 이용해, 다음과 같이 권한을 설정하였습니다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception
{
http
.authorizeHttpRequests((authorizeRequests) -> authorizeRequests
.requestMatchers("post/new").authenticated()
.requestMatchers("post/{id}/comment/new").authenticated()
.anyRequest().permitAll())
.formLogin((formLogin) -> formLogin
.loginPage("/login")
.defaultSuccessUrl("/"))
.logout((logout)->logout
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true)) //세션삭제
;
return http.build();
}
Thymeleaf Extras Spring Security를 통해 로그인상태일경우, 로그아웃이 표현되도록 하는 등의 회원관련 디테일을 추가했습니다.
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
...
<a sec:authorize="isAnonymous()" th:href="@{/register}" class="btn">회원가입</a>
<a sec:authorize="isAnonymous()" th:href="@{/login}" class="btn">로그인</a>
<a sec:authorize="isAuthenticated()" th:href="@{/logout}" class="btn">로그아웃</a>
3 : 팀프로젝트-구인구직 플랫폼
깃허브 링크
방학 때 진행한 마지막 프로젝트로, 교내 스타트업대회에서 프로토타입으로 보여줬던 만큼, 아키텍처 뿐만 아니라 ui/ux에도 신경을 썼던 프로젝트입니다.
팀원 모두 프론트엔드 개발 경험이 적어 개발 과정 중 ui부분이 가장 어려웠습니다.
피그마로 어느정도 틀을 짠 뒤, 이를 바탕으로 코드로 구현했습니다.
-
회원서비스(사장/알바/관리자)
- 회원가입
- 로그인/아웃
-
공고글
- 작성
- 삭제
- 검색
-
지원서
- 작성
- 삭제
- 승인
-
api
- google maps
백엔드에서는 서비스 계층에서 인터페이스를 도입해 유지보수를 쉽게 할 수 있도록 구현했습니다.
유저 유형은 사장과 알바생 두 종류인 만큼, 유저 엔티티를 어떻게 만들지에 대한 고민이 있었고, 최종적으로는 공통부분을 담는 유저 엔티티와, 이를 각각 상속시켜 두 종류의 엔티티를 만들었습니다.
계층간 데이터 전송 시, dto를 적절히 사용해 데이터를 감싸는 것에 신경을 썼고, 이를 위한 dtoConverter도 추가로 구현하였습니다.
추가로, 연습삼아 google maps api를 통해, 지도에 공고글의 편의점 위치를 마커로 표시하는 기초적인 기능을 다음과 같이 구현해보았습니다.
이 프로젝트의 아이디어를 통해 교내대회에서 우승하였습니다.
세번째 프로젝트는 아마 학기가 시작되면 처음부터 다시 개발해볼 생각입니다. 방학 때는 우선 플랫폼의 구현과 기능 자체 위주로 개발하다보니, 아무래도 유지보수나 가독성, 예외처리 등의 부분에서 문제가 있을 수 밖에 없었기에 다시 개발하는 과정을 통해 더 개선시킬 예정입니다.
이번 방학 때 웹 백엔드 위주의 개발과 공부를 했기에, 위 웹의 api를 기반으로, 모바일 앱 개발과 React 등을 사용한 프론트앤드를 공부하는 쪽으로 방향을 잡아보거나, 백엔드에 더 집중해 자세히 공부하지 못했던 JPA 등을 공부해볼 생각입니다.