6. Spring MVC 를 이용한 게시판 구현연습

Spring MVC를 이용한 웹앱 제작(게시판연습)

프로젝트 기본구조 중 추가한 라이브러리

Devtools
lombok
JPA
Mysql
Thymeleaf
Web

추가적으로 thymleaf의 레이아웃 라이브러리를 받았다.

<!-- https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect -->
<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>2.3.0</version>
</dependency>

application.properties 에 기본적으로 들어갈 내용

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/{DB명}?useSSL=false
spring.datasource.username={유저이름}
spring.datasource.password={비밀번호}

spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

logging.level.org.hibernate=true

spring.thymeleaf.cache=false
logging.level.org.springframework.web=info
logging.level.org.djlee=info

PageableDefault를 통해 컨트롤러의 적용방법

@GetMapping("/list")
    public void list(
        @PageableDefault(
            direction=Sort.Direction.DESC,
            sort="bno",
            size=10,
            page = 0) Pageable page) {

            log.info(page);
    }

장점

  • 쉽게 parameter 를 전달하여 게시판을 만들 수 있다는 장점이 있다.

단점

  • url에서 sort,size,page에 대한 조작을 parameter로 전달하기 때문에 고의적인 공격에 취약하다.

대처법

  • 별도의 파라미터를 수집해서 처리하는 Value Object를 생성하여 문제를 해결한다.

PageVO

package org.xxx.vo;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

public class PageVO {
    private static final int DEFAULT_SIZE =10;
    private static final int DEFAULT_MAX_SIZE=50;

    private int page;
    private int size;

    public PageVO() {
        this.page=1;
        this.size=DEFAULT_SIZE;
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page < 0? 1 : page;
    }
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size < DEFAULT_SIZE || size >DEFAULT_MAX_SIZE? DEFAULT_SIZE : size;
    }
    public Pageable makePageable(int direction, String... props) {
        Sort.Direction dir = direction == 0 ? Sort.Direction.DESC : Sort.Direction.ASC;
        return PageRequest.of(this.page -1, this.size,dir,props);
    }
}

Controller

@Autowired
        WebBoardRepository repo; 

        @GetMapping("/list")
        public void list(PageVO vo,Model model) {

            Pageable page = vo.makePageable(0, "bno");

            Page<WebBoard> result = repo.findAll(repo.makePredicate(null, null), page);


            log.info(""+page);
            log.info(""+result);

            model.addAttribute("result",result);

        }

View 화면

<div layout:fragment="content">
        <div class="panel-heading">List Page</div>
        <div class="panel-body">
            <p>[[${result}]]</p>
            <div>[[${result.content}]]</div>
        </div>
    </div>

Jquery에서 href 속성을 갖고 싶은데 못갖을 떄 해결법

예를들어 a 태그에서 href의 속성을 그대로 쓰고 싶다면 어떻게 해야 될까?

$('a').click((e)=> {
    var target = e.target(); // 현재 타겟에 대한 obj가 필요하다.
    e.preventDefault();     // 버블링을 막기위해 필요하다.
    target.attr('href')     // 이제 사용가능
});

생각보다 attr 속성의 href를 받기에 오류가 발생할 때도 많은데 이럴때 jQuery를 이용한다면 대상에 대해 obj를 만들어 쓸 생각을 하자.

Last updated