스프링부트 게시판 만들기 제7강 게시글 목록

  

스프링 부트 게시판 만들기

제7강 게시글 목록

 

띄엄띄엄 글을 쓰다보니, 어디까지 설명했는지 잊고 진행했었네요~

6강까지를 통해서 스프링부트 프로젝트 생성에서 Database, MVC 까지 흐름이 전체적으로 설명이 된거 같고요.

이제부터 개별적으로 게시글목록상세페이지, 파일업로드, 파일다운로드 등을 설명해나가도록 하겠습니다.

오늘은 게시글 목록을 만들어보겠습니다.

목록 기능에 사용되는 소스 부분만 분리하여 내용을 만들었습니다.

 

package com.soledot.board.boardarticle;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLConnection;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author soledot
 * @since 20191108
 * @version soledot
 * @description boardarticle Controller
 *
*/

@Controller
@RequestMapping("/boardarticle/*")
public class BoardarticleCtrl {

	private static final Logger logger = LoggerFactory.getLogger(BoardarticleCtrl.class);

	@Autowired BoardarticleSvc boardarticleSvc;

	//---* 리스트
	@RequestMapping("boardarticlelist.sd")
	public String list( @RequestParam Map<String, Object> param, ModelMap model ){

		try{
			boardarticleSvc.list( param, model );
		}catch( Exception e ){
			logger.error( e.toString(), e );
		}

		return "boardarticle/boardarticlelist";
	}
	
}

 

http://localhost:8080/boardarticle/boardarticlelist.sd 로 요청이 왔을 경우 list method에서 받아서

바로 BoardarticleSvc의 구현클래스 BoardarticleSvcImpl의 list method로 보내줍니다.

controller는 요청을 받아서 Service로 넘겨주는 역할만 충실히 합니다.

그리고 BoardarticleSvcImpl의 list method의 처리가 완료되면, boardarticle 폴더 안에 boardarticlelist.jsp 페이지로 보냅니다.

 

package com.soledot.board.boardarticle;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author soledot
 * @since 20191108
 * @version soledot
 * @description boardarticle Service Interface
 *
*/

public interface BoardarticleSvc {

	//---*fo 리스트map
	public boolean list( Map<String, Object> param, ModelMap model )throws Exception;


}

 

인터페이스 BoardarticleSvc입니다.

method를 정의하고 실제 처리는 BoardarticleSvcImpl에서 구현합니다.

 

package com.soledot.board.boardarticle;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author soledot
 * @since 20191108
 * @version soledot
 * @description boardarticle Service 구현 클래스
 *
*/

@Service("BoardarticleSvc")
public class BoardarticleSvcImpl implements BoardarticleSvc {

	private static final Logger logger = LoggerFactory.getLogger(BoardarticleSvcImpl.class);

	@Autowired BoardarticleDao boardarticleDao;

	//---*fo 리스트map
	@Override
	public boolean list( Map<String, Object> param, ModelMap model ) throws Exception {

		Map<String, Object> svcMap = new HashMap<>();

		svcMap.put( "startrow", 0 );  //--- 게시글 시작 번호
		svcMap.put( "endrow", 10 );   //--- 가져올 게시글 개수
		svcMap.put( "orderby", "seq desc" );  //--- 정렬

		List<Map<String, Object>> boardarticleList = boardarticleDao.list( svcMap ); //--- Dao의 list method를 호출해서 게시글 목록 가져오기


		int count = boardarticleDao.cnt( svcMap );  //--- 페이징 처리를 위해 게시글 전체 count를 가져오기.

		model.put( "boardarticleList", boardarticleList );  //--- 목록 model에 담기. view로 가져가기 위해서
		model.put( "count", count);
		
		return true;
	}

}

 

BoardarticleSvc 구현 클래스 BoardarticleSvcImpl입니다.

svcMap에 조건을 담아서 Data를 가져오기 위해서 BoardarticleDao의 list method를 호출합니다.

startrow, endrow는 paging 처리를 위한 준비 된 Parameter입니다. Parameter만 있을 뿐 페이징처리가 구현 된 것은 아닙니다.

 

package com.soledot.board.boardarticle;

import java.util.List;
import java.util.Map;

/**
 * @author soledot
 * @since 20191108
 * @version soledot
 * @description boardarticle Dao Interface
 *
*/

public interface BoardarticleDao {

	//---*카운트(Map)
	public int cnt( Map<String, Object> param );

	//---*리스트
	public List<Map<String, Object>> list( Map<String, Object> param );


}

 

interface BoardarticleDao는 역시 method를 정의만 하고 DaoImpl에서 구현합니다.

 

package com.soledot.board.boardarticle;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * @author soledot
 * @since 20191108
 * @version soledot
 * @description boardarticle Dao 구현 클래스
 *
*/

@Repository("BoardarticleDao")
public class BoardarticleDaoImpl implements BoardarticleDao {

	@Autowired private SqlSession sqlSession;

	//---*카운트(Map)
	@Override
	public int cnt( Map<String, Object> param ){
		return sqlSession.selectOne( "boardarticle.cnt", param );
	}

	//---*리스트
	@Override
	public List<Map<String, Object>> list( Map<String, Object> param ){
		return sqlSession.selectList( "boardarticle.list", param );
	}


}

 

각 method는 boardarticle.xml의 쿼리를 통해 Database의 Data를 가져오게 됩니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="boardarticle">

	<select id="cnt" parameterType="hashmap" resultType="int">
		SELECT COUNT(*) FROM BOARDARTICLE
        <!-- 아래 parameter 있을 경우 where가 자동으로 삽입됨. -->
		<where>
            <!-- 조건이 하나일 경우에는 AND가 붙지 않고, 앞에 조건이 있을 경우에만 AND가 자동으로 삽입됨 -->
			<if test="null != seq and '' != seq">AND SEQ = #{seq}</if>
			<if test="null != title and '' != title">AND TITLE = #{title}</if>
			<if test="null != content and '' != content">AND CONTENT = #{content}</if>
			<if test="null != filename and '' != filename">AND FILENAME = #{filename}</if>
		</where>
        <!-- 아래 parameter 있을 경우 where가 자동으로 삽입됨. -->
	</select>

	<select id="list" parameterType="hashmap" resultType="hashmap">
		SELECT * FROM BOARDARTICLE
		<where>
			<if test="null != seq and '' != seq">AND SEQ = #{seq}</if>
			<if test="null != title and '' != title">AND TITLE = #{title}</if>
			<if test="null != content and '' != content">AND CONTENT = #{content}</if>
			<if test="null != filename and '' != filename">AND FILENAME = #{filename}</if>
		</where>
		<if test="null != orderby and '' != orderby">ORDER BY ${orderby}</if>
		<if test="null != endrow and 0 lt endrow">LIMIT #{startrow}, #{endrow}</if>
	</select>

</mapper>

 

boardarticle.xml 내용입니다.

orderby의 경우 다른 parameter와는 다르게 ${orderby}로 처리 되었습니다.

전달받은 parameter 그대로 사용하게 되면 SQL Inject 공격을 당할 수 있으니 주의하시기 바랍니다.

 

자 이제 마지막으로 boardarticlelist.jsp 파일 입니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html lang="ko">
<head>
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" type="text/css" />
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body >
	<div class="container">
		<form action="boardarticlelist.sd" class="form-horizontal" id="frm" name="frm" method="post">			
			<div class="row">
				<div class="col-md-12">
					<h2>게시글 리스트</h2>

					<table class="table table-bordered table-hover" >
						<thead>
							<tr>
								<th>제목</th>
								<th>등록일</th>
							</tr>
						</thead>
						<tbody>
							<!-- model에 담겨진 boardarticleList를 반복문으로 처리 -->
							<c:forEach items="${boardarticleList}" var="boardarticle" varStatus="status" >
								<tr>
									<td>
										<a href="boardarticleview.sd?seq=${boardarticle.seq}">${ boardarticle.title }</a> <!-- 클릭 시 상세화면으로 이동하기 위해 링크가 있습니다. -->
									</td>
									<td>${ boardarticle.indate }</td>
								</tr>
							</c:forEach>
							<!-- model에 담겨진 boardarticleList를 반복문으로 처리 -->
						</tbody>
					</table>

					<div class="form-group">
						<a class="btn btn-info" href="boardarticleadd.sd" title="등록"> 등록</a>
					</div>

				</div>
			</div>
		</form>
	</div>

	<script type="text/javascript">

		function dataList(){
			$('#frm').submit( 'boardarticlelist.sd' );
		}

		function dataAdd(){
			$('#frm').submit('boardarticleadd.sd' );
		}


		function dataView(seq){
			$('#seq').val(seq);
			$.soledot.submit( '', 'boardarticleview.sd' );
		}

	</script>

</body>
</html>

 

이제, 테스트만 진행해보면 됩니다.

http://localhost:8080/boardarticle/boardarticlelist.sd로 접속해보세요~

아래와 같은 목록 페이지가 출력됩니다.

 

 

잘 출력 되시는지~

 

공유하기:

스프링부트 카테고리 글 :

0 Comments

Comment