Stay Hungry Stay Foolish

PROJECT/[스프링 부트] 게시판

[스프링 부트] 4. 게시판 만들기 게시글 작성폼 생성과 처리

dev스카이 2023. 10. 23. 13:14

01. HTML 파일 생성

board > src > main > resources > templates에 HTML 파일을 생성한다. 

 

그리고 아래와 같이 작성해준다.

태그 해석

• <title> - 타이틀 명은 '게시물 작성 폼'이라고 한다. 

• <div> - 분할하다는 뜻의 Division의 준말로, HTML문서 내에서 한 개의 가로 공간(Block)을 만드는 태그이다.

  • id, class 속성
    모든 태그에는 id 속성과 class 속성을 지정해 줄 수 있는데, 이를 이용하면 CSS나 JavaScript에서 태그를 좀더 쉽게 다룰 수 있다. id는 원칙상 하나의 id당 하나의 태그에만 적용 할 수 있으며, class는 하나의 class를 여러 태그에 적용 할 수 있다.

• <textarea> - 사용자가 여러 줄의 텍스트를 입력할 수 있는 텍스트 입력 영역을 정의할 때 사용한다.

• <input> - <textarea>와 같이 데이터를 받는 태그이다.

• <button> - 클릭할 수 있는 버튼을 정의할 때 사용한다.

 

01-1. BoardController

컨트롤러에서 html로 이동하는 주소가 필요하므로 컨트롤러에 url 연결

해석 : localhost:8080/board/write에 접속하면 boardwrite.html을 보여주겠다.

 

 

실행하기 - http://localhost:8080/board/write로 접속

접속한 결과 html에서 작성한대로 만들어진 것을 볼 수 있다.

 

좀 더 정형화 된 모양으로 바꾸고 싶으면 아래와 같이 html파일에서 변경하면 된다.

변경한 후에 재실행 한 결과 좀 넓고 깔끔하게 정리된 것을 볼 수 있다.

 

정리하면, html에서 작성한 것을 controller에 url을 지정하고 해당 url을 검색하면, 스프링 부트가 controller에서 매핑된 것을 찾아 html 파일을 보여준다. (완벽한 개념은 아니지만 쉽게 말하면)

 

02. 게시물 작성 처리

제목과 게시물에 글을 적고 작성 버튼을 눌러도 아무 일도 일어나지 않는다. 따라서 이런 걸 처리하기 위해서 추가로 작업이 필요하다.

 

02-1. boardwrite.html

• <form> - 전체 양식을 의미하며, 화면에 보이지 않는 추상적인 태그이다. 실제로 사용자가 양식을 입력하기 위한 태그는 <input> 태그 등이 사용된다.

  • <form> 태그의 action 속성은 폼 데이터(form data)를 서버로 보낼 때 해당 데이터가 도착할 URL을 명시한다.
  • <form> 태그의 method 속성은 폼 데이터(form data)가 서버로 제출될 때 사용되는 HTTP 메소드를 명시한다.
  • method의 속성 중 post는 폼 데이터를 HTTP POST 메소드로 전송한다.

  <textarea> 태그의 name 속성은 <textarea> 요소의 이름을 명시한다. 

  <button> 태그의 type 속성은 해당 버튼의 타입(type)을 명시한다. 브라우저별로 <button> 요소에 대한 서로 다른 기본 타입을 사용할 수 있으므로, <button> 요소에는 언제나 type 속성을 명시해야 한다.

  • type의 속성 중 submit은 해당 버튼이 폼 데이터(form data)를 제출하는 제출 버튼(submit button)임을 명시한다.

 

정리하면, button을 눌렀을 때 form 내에 있는 input과 textarea의 데이터가 /board/writedo 주소로 넘어가게 된다.

 

02-2. style 재수정

위와 같이 style을 재수정한다. '>' 꺽쇠라고 하는데, 왼쪽 피연산자를 부모라고 하고 오른쪽 피연산자를 자식이라고 한다.

 

꺽쇠가 있을 때 클래스가 layout인 태그 내의 모든 input 태그 중에서 자식인 input태그에 대해서만 적용이 된다. 이걸 자식 선택자라고 한다.

반대로, 꺽쇠가 없을 때 클래스가 layout인 태그 내의 모든 input 태그가 속성 값대로 적용이 된다. 이걸 하위 선택자라고 한다.

 

재실행(재실행 할 때는 상단의 빨간색 정지 버튼을 누르고 난 후 재실행을 해야 한다.) 

작성 버튼을 눌러보면 다음과 같은 404 페이지가 뜬다.

writedo 페이지를 만들지 않아서 위와 같이 뜬 것이다. 중요한 것은 작성 버튼을 눌렀을 때 writedo 주소로 넘어가는지 확인하는 것이다. 

 

02-3. BoardController 수정

게시글 작성 처리를 하기 전에 데이터가 넘어오는지 확인을 해준다.

@PostMapping : 주어진 URL 표현식과 일치하는 HTTP POST 요청을 처리하는 역할을 한다. html파일에서 설정했던 url과 일치해야 한다. 그럼 컨트롤러에서 제목과 내용을 뿌려준다.

 

확인(localhost:8080/board/write에서 제목과 글을 쓰고 버튼을 눌러보기)

그러면 아까와 같은 에러 페이지가 뜨는데 return에 넘어갈 페이지를 안 넣어줘서 그런 것이다. 일단은 데이터가 넘어갔는지 확인만 해본다.

/board/write에서 작성한 데이터가 그대로 적혀 있다. 정상적으로 데이터가 넘어간 것을 볼 수 있다.

 

03. Entity 생성

위에서 작성한 제목과 내용이 DB에 저장이 되어야 하는데 이때 필요한 건 repository(저장소)이다. 먼저 패키기와 클래스를 생성한다.

 

03-1. 패키지와 클래스 생성

Board > src > main > java > com.study.board 패키지 내에 repository와 entity라는 패키지를 생성하고, entity내에는 Board라는 클래스를 생성한다.

 

03-2. Board 클래스

필드 타입과 이름은 MySQL에서 Board테이블을 만들고 컬럼을 만들었을 때와 같이 형식에 맞게 적어준다.

 

@Entity : 테이블을 의미하는 것으로, 테이블과 매핑이 된다. @Entity가 붙은 클래스는 JPA가 관리한다.

@Id : 기본키를 나타내기 위한 어노테이션이다. 해당 필드를 기본키로 매핑한다.

@GeneratedValue : 기본키를 자동으로 생성할 때 @Id와 함께 사용되어야 하는 어노테이션이다. 

  • strategy = GenerateType.IDENTITY : 기본키 생성을 DB에게 위임하는 방식으로 id값을 따로 할당하지 않아도 DB가 자동으로 AUTO_INCREMENT를 하여 기본키를 생성해준다.

 

위와 같이 @Entity라는 어노테이션을 적어주면 JPA가 Board 클래스를 읽어들이고 처리해준다.

 

03-3. BoardController 수정

 

html을 보면 작성 폼에서 작성 버튼을 눌렀을 때, title에 제목을 작성한 것과 content에 적은 내용이 Controller에서의 매개변수 title과 content에 담겨서 들어오게 된다. 그러나 이게 많아지다 보면 번거롭기 때문에 수정한다.

board내에 있는 title을 받아야 하는데 이때 필요한 게 lombok이다. Board Entity에서 @Data 어노테이션을 추가한다.

@Data : @Getter / @Setter, @ToString, @EqualsAndHashCode와 @RequiredArgsConstructor, @Value 를 한꺼번에 설정해주는 어노테이션이다.

 

제목이 Entity로 넘어가는 지 확인

제목만 받는 걸로 했으니깐 제목만 입력해주고 전송 버튼을 눌러주면 아까와 같은 오류 페이지가 뜬다.

데이터가 정상적으로 넘어가는 것만 볼 거기 때문에 오류는 무시한다. 제목에 적은 데이터 그대로 넘어간 것을 볼 수 있다.

 

04. repository 생성

board > src > main > java > com.study.board > repository에 Interface를 생성한다.

 

04-1. BoardRepository

  @Repository : 자동으로 스프링 빈으로 등록한다. @Component의 구체화된 형태 중 하나로 DB에 접근한다.

  extends : 상속을 받고자 할 때 사용한다.

 JPARepository : JPARepository 인터페이스를 상속받는 인터페이스를 정의하면, 해당 인터페이스를 구현하는 클래스는 JPA에서 제공하는 메서드들을 사용할 수 있다.

  • 데이터베이스의 추가, 조회, 수정, 삭제의 findAll(), findById(), save() 등의 메서드들을 사용할 수 있다.
  • 제공되는 메서드들 이용하여 쉽고 간편하게 CRUD 조작을 할 수 있다.
  • 즉, JpaRepository를 사용하면, 복잡한 JDBC(Java DataBase Connectivity) 코드를 작성하지 않아도 간단하게 DB와의 데이터 접근 작업을 처리할 수 있다.
  • 형식은 JpaRepository<T, ID> 이고, Entity 명과 기본키로 지정한 필드의 타입을 넣어준다.

 

04-2. Service 생성

board > src > main > java > com.study.board 에 service패키지를 생성하고 service 패키지 내에 클래스를 하나 생성한다.

 

※ Service를 생성하는 이유Service는 Controller와 Repository를 잇는 역할을 한다. 만약 Service가 없다면 Controller에서 직접 데이터를 받아 가공하고 처리하여 View에 넘겨주어야 하므로 Controller에는 코드가 길어지고, 중복되는 코드가 많아질 것이다.

 

04-3. BoardService

 @Service : 자동으로 스프링 빈으로 등록한다. @Component의 구체화된 형태 중 하나이다.

@Autowired : DI(Dependency Injection) (DI에 관련된 내용은 추후에)

 save() : jpa에 save라는 메소드가 있는데, 파라미터로 넘겨준 엔티티를 직접 업데이트 한다.

 

04-4. BoardController 수정

컨트롤러에도 서비스 객체를 추가하고, 역시 @Autowired를 DI해준다. 서비스에서 추가해준 write메소드를 사용한다. 

 

05. DB에 데이터가 들어갔는지 확인하기

이제 데이터가 DB에 정상적으로 들어가는지 확인을 해본다.

MySQL Workbench에서 테이블을 확인하면 현재 데이터가 없는 것을 볼 수 있다. 작성 폼에서 제목과 내용을 적어주고 확인해보자.

작성 폼에서 위와 같이 적어주고 버튼을 누르면 오류 페이지가 뜬다. 그러나 우리가 확인할 것은 테이블이다.

새로고침 버튼을 누르고 테이블을 확인해보면 위에서 적었던 데이터가 정상적으로 들어간 것을 볼 수 있다.

 

이처럼 JPA를 사용해서 DB에 접근할 수 있다.