티스토리 뷰
프로젝트 구조 살펴보기
Spring Starter Project로 프로젝트를 생성했을 때 깡통 프로젝트의 구조는 다음과 같다.
최상위 폴더로는 bin, gradle, src가 있다.
그 아래 build.gradle 파일은 gradle이 사용하는 환경 파일이다.
gradle은 groovy를 기반으로 한 빌드 도구로, Ant, Maven과 같은 이전 세대의 단점을 보완한 도구.
라이브러리를 가져오도록 하는 환경 파일이다.
프로젝트에 필요한 라이브러리를 설치할 때 내용을 작성한다.
여기서 bin, gradle 폴더는 넘어가고 src 폴더만 살펴보도록 하겠다.
src 하위에 main, test 디렉토리가 있다.
main 디렉토리 : 실제적인 코드를 작성하는 영역
test 디렉토리 : 테스트 코드를 작성하는 영역
main 아래로 java, resources 디렉토리가 있다.
src/main/java 디렉토리 : java 파일을 저장 (컨트롤러, 폼, DTO, 엔티티, 서비스 등의 java 파일)
src/main/resources 디렉토리 : java 파일을 제외한 html, css, js, 환경파일(application.properties) 파일을 저장
여기서 주목할 점.
resources 아래로 static 디렉토리, templates 디렉토리, application.properties 가 있다.
src/main/resources/static 디렉토리 : css, js, 이미지 파일을 저장
src/main/resources/templates 디렉토리 : html 파일을 저장
application.properties : 환경설정을 세팅하는 파일 (디비연결, 타임리프 설정 등)
실제로 html 파일을 작성하면서 링크를 연결할 일이 많은데
css, js, 이미지파일의 경우 static을 루트 폴더로 인식하고,
html 파일을 불러올 땐 templates을 루트 폴더로 인식한다.
그러므로 폴더를 잘 구분해서 써야한다!
프로젝트명 + Application.java
: 스프링부트 프로그램의 시작을 담당하는 파일이다.
package com.study.board;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BoardApplication {
public static void main(String[] args) {
SpringApplication.run(BoardApplication.class, args);
}
}
프로젝트명을 'board'로 지었기 때문에
시작 프로그램 파일의 이름이 BoardApplication.java 라고 자동 생성 되었다.
이러한 시작 프로그램에는 반드시 @SpringBootApplication 어노테이션이 적용되어 있어야 한다.
그래야 스프링부트 애플리케이션을 시작할 수 있다.
아래 내용은 "점프 투 스프링부트"의 실습과정을 모두 마친 후의 프로젝트 구조를 보고 추가적으로 서술한 내용이다.

src > main > java > com > study > board 아래에
answer, main, question, siteUser 폴더를 생성하였다.
답변, 메인화면, 질문, 유저기능(회원가입, 로그인과 같은 기능) 별로 폴더를 나눴다.
src > main > resoucres 아래에
static 에는 부트스트랩의 css와 js, 그리고 내가 작성한 style.css 파일이 있다.
templates 에는 common 폴더를 두어 공통으로 사용할 수 있는 레이어 템플릿을 따로 뺐다.
formErrors.html 은 경고문구를 표출해주는 div ,
layout.html은 헤더, 푸터, 본문, 네비게이션 등의 위치를 정해주는 레이아웃 파일 ,
navbar.html 은 네비게이션의 파일이다.
<프로젝트 구조를 짜면서 느낀 점>
폴더를 위와 같이 "사용자 기능별"로 나눌지, "역할별"로 나눌지 어떤게 나은건지 생각해봤다.
* 역할별의 의미 : controller, dto, service, repository 처럼 역할별로 폴더를 두고 관리하는걸 의미
근데 프로젝트 규모가 커진다고 가정할 때,
역할별로 나누면 나중에 관리가 힘들 것 같다는 생각이 들었다.
사용자 기능별로 나누면 직관적으로 보기도 쉽다.
실제 실습도 사용자 기능별로 진행되어서 나도 똑같이 진행했다.
컨트롤러와 ResponseBody
package com.study.board.main;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@GetMapping("/test1")
public void test1() {
System.out.println("index");
}
@GetMapping("/test2")
@ResponseBody
public String test2() {
return "Hello_World";
}
@GetMapping("/")
public String getMain() {
return "redirect:/question"; //question.html 출력
}
}
- 컨트롤러 작성 시, @Controller 선언 필수
- test1() 메서드의 GetMapping 인 /test1 으로 요청시,
콘솔창에는 [index]라고 출력되지만 화면에는 500 오류가 발생한다.
--> URL과 매핑된 메서드는 결과값을 리턴해야 하는데 아무 값도 리턴하지 않아 오류가 발생한 것.
오류를 해결하려면 클라이언트(브라우저)로 응답을 return 해야 한다.
-test2() 메서드의 GetMapping 인 /test2 으로 요청시, return 값은 "Hello_World" 이다.
@ResponseBody 어노테이션은 URL 요청에 대한 응답으로 문자열을 리턴하라는 의미로 쓰인다.
즉, Hello_World.html을 호출하는 것이 아닌, 문자열 그 자체 [Hello_World]를 브라우저에 return한다.
- @GetMapping("/") 로 접근 시, question.html 으로 redirect 해주도록 하였다.
이때는 @ResponseBody 어노테이션이 없으므로, 문자열이 아닌 html 파일로 해석한다.
@ResponseBody 의 경우 ajax와 상성이 잘 맞다.
//회원가입
@PostMapping(value="/insertUser")
@ResponseBody
public ModelMap insertUser(UserDTO userDTO) {
int result = userService.insertUser(userDTO); // user insert
ModelMap model = new ModelMap();
model.addAttribute("resultCd", result);
return model;
}
이러한 회원가입 메소드가 있다고 하자.
위 메소드는 사용자가 회원가입 화면(signUp.html)에서 입력폼을 작성 후,
가입하기 버튼을 누를 때 ajax로 호출된다고 가정하자.
이때 메소드에는 @ResposeBody가 선언되어 있고,
매개변수는 UserDTO, return 형은 ModelMap 이다.
화면에서 파라미터들이 userDTO에 담겨서 넘어오고,
int result = userService.insertUser(userDTO) 실행 시,
result 변수에 해당 쿼리의 결과 코드가 담기게 만들었다.
result = 1 이면 유저가 정상적으로 인서트 된 거고,
result = -1 이면 오류가 났음을 표시하는 값으로 체크를 하기로 했다.
result 값을 model의 "resultCd" 로 담고 return model 해주면,
ajax에 의해 그 결과 값이 화면에 가져와진다.
model.resultCd 값이 음수이면, alert 창에 "가입할 수 없습니다" 를 표출해주고,
model.resultCd 값이 1이면 "회원가입이 완료되었습니다" 를 표출하고 메인화면으로 돌아가게 할 수 있다.
'점프투스프링부트(스프링부트+JPA)' 카테고리의 다른 글
2장 2-05 요약 (리포지터리 생성 방법, JUnit 설치와 테스트 코드 작성, 리포지터리 메서드명 작성 규칙, JUnit 에서 발생하는 지연 방식과 즉시 방식) (0) | 2024.12.13 |
---|---|
2장 2-04 요약 (데이터베이스와 엔티티, 엔티티 코드 리뷰) (3) | 2024.12.13 |
2장 2-03 요약 (ORM 개념, JPA 개념, H2 데이터베이스 설치와 환경설정, JPA 환경설정) (1) | 2024.12.12 |
1장 스프링부트 개발 준비하기 1-03, 1-04 요약 (웹 서비스 동작 원리, IP와 도메인, localhost:8080 이해) (0) | 2024.12.11 |
1장 스프링부트 개발 준비하기 1-01, 1-02 요약 (스프링부트 개념, 개발환경 준비, 프로젝트 생성) (2) | 2024.12.10 |