Naver SmartEditor 2.0 적용하기 - DB 저장, 출력

이번 포스팅에서는 스마트 에디터에서 작성한 내용을 DB에 저장하고, 상세 페이지에 출력까지 해 볼 예정이다.

 

🔹 스마트 에디터로 작성한 내용 Ajax로 DB 저장

◽ DB 세팅하기

resources/application.yml

server:
  port: 8085
  servlet:
    context-path: /blog
    encoding:
      charset: UTF-8
      enabled: true
      force: true

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/blog?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul
    username: 아이디
    password: 비밀번호

  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true
    defer-datasource-initialization: true

  thymeleaf:
    check-template-location: true
    prefix: classpath:/templates/
    suffix: .html
    cache: false
    enabled: true

 

◽ DTO

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class AddArticleRequest {
    private String title;
    private String content;

    public Article toEntity() { // 생성자를 사용한 객체 생성
        return Article.builder()
                .title(title)
                .content(content)
                .build();
    }
}

 

◽ Service

@RequiredArgsConstructor
@Service
public class BlogService {
    private final BlogRepository blogRepository;
    
    // 블로그 글 추가 메소드
    public Article save(AddArticleRequest request) {
        return blogRepository.save(request.toEntity());
    }
}

 

◽ Controller

@PostMapping("/newArticleInsert")
    public ResponseEntity<String> newArticleInsert(@RequestBody AddArticleRequest request) {
        blogService.save(request);
        return ResponseEntity.ok("Success");
}

 

◽ Repository

public interface BlogRepository extends JpaRepository<Article, Long> {
 // JPA에서 기본으로 제공되는 메소드는 선언없이 사용 가능
}

 

◽ Ajax로 내용 전송하기

백엔드 구성을 모두 끝냈다면, 이제 자바스크립트에서 게시글 내용을 전송하면 된다.

이 전에 작성했던 코드에 Ajax로 서버에 전송하는 부분을 추가해 줬다.

function submitPost() {
    oEditors.getById["editorTxt"].exec("UPDATE_CONTENTS_FIELD", [])
    let title = document.getElementById("post-title-inp").value
    let content = document.getElementById("editorTxt").value

    if (title == '') {
        alert("제목을 입력해주세요.")
        let titleInput = document.getElementById("post-title-inp");
        if (titleInput) {
            titleInput.focus();
        }
    } else if (content == '') { // 비어있는 경우
        alert("내용을 입력해주세요.");
        oEditors.getById["editorTxt"].exec("FOCUS");
        return;
    } else {
        let writePost = {
            title: $("#post-title-inp").val(),
            content: content
        };

        $.ajax({
            url: "/blog/newArticleInsert",
            data: JSON.stringify(writePost),
            type: 'POST',
            contentType: "application/json",
            success: function(data) {
                console.log('success');
                alert('저장되었습니다.');
                window.location.href = '/blog/index'; // 등록 후 index.html로 리다이렉션
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                alert('오류가 발생하였습니다.');
            }
        });
    }
}

 

🔸 결과화면

 

데이터를 확인해 보면 잘 저장되는 것을 확인할 수 있다 !

 

🔹 DB에 저장된 데이터 출력해 보기

필자는 아래와 같은 방식으로 출력을 해보려고 한다.

  • 목록 페이지 : html 태그와 스타일을 제거한 글만 출력
  • 상세 페이지 : html 태그와 스타일을 유지해서 출력

 

◽ 목록 페이지 

목록 페이지에서는 html 태그와 스타일을 제거한 글만 출력하기 위해 'DTO'를 수정했다.

@Getter
public class ArticleListViewResponse {
    private final Long id;
    private final String title;
    private final String content;

    public ArticleListViewResponse(Article article) {
        this.id = article.getId();
        this.title = article.getTitle();
        this.content = stripHtmlTags(article.getContent());
    }

    private String stripHtmlTags(String html) {
        // HTML 태그 제거
        String strippedHtml = html.replaceAll("<[^>]*>", "");
        // &nbsp; 문자 제거
        strippedHtml = strippedHtml.replaceAll("&nbsp;", " ");
        return strippedHtml;
    }
}

 

◽ 상세 페이지

상세 페이지에서는 html 태그와 스타일을 유지해서 출력하기 위해 타임리프 문법 중 'th:utext'를 사용했다.

<div class="inner">
    <!-- HTML 태그를 그대로 출력하기 위해 th:utext 사용 -->
    <div class="article-view" th:utext="${article.content}">
    </div>
</div>

 

🔸 결과화면

목록 페이지

 

상세 페이지

 

 

 

 

 

스마트 에디터로 작성한 내용을 DB에 저장하고 출력까지 해봤다 !

그리 어렵지 않은 api 적용이었지만 오랜만에 프로젝트를 진행하면서 버벅거렸던 부분이 많아 블로그에 정리하게 되었다.

앞으로 싱글 사진, 멀티 사진, 동영상 업로드를 프로젝트에 진행하게 된다면 이어 포스팅을 할 예정이다 ! 😊

 

 

 

 

 

 

📃 reference