20240223 스프링(파일 체크, 파일 업로드 , 갤러리 만들기)
2024. 2. 23. 17:49ㆍ2023.11.21-2024.05.31
public String fileUpload(MultipartFile upFile) {
//경로 저장
String root = req().getSession().getServletContext().getRealPath("/");
String upfilePath = root + "resources\\upfile\\";
//UUID
UUID uuid = UUID.randomUUID();
//uuid를 포함한 파일명
String newFileName = uuid.toString()+ upFile.getOriginalFilename();
//실제 업로드
File file = new File(upfilePath, newFileName);
try {
upFile.transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return newFileName;
}
//파일 업로드 -> util
String newFileName = util.fileUpload(upFile);
dto.setGfile(upFile.getOriginalFilename());
int result = galleryService.galleryInsert(dto);
return "redirect:/gallery";
파일jsp > onsubmit="fileCheck()" 추가
<form action="./file" method="post" enctype="multipart/form-data" onsubmit="fileCheck()">
스크립트 만들기
<script type="text/javascript">
function fileCheck(){
var fileVal = $("#file1").val();// 파일이름 가져오기
if( fileVal == ""){
alert('파일을 선택하세요.');
return false;
} else {
var ext = fileVal.split('.').pop().toLowerCase();//확장자분리
//아래 확장자가 있는지 체크
if($.inArray(ext, ['jsp', 'jpeg','gif', 'png']) == -1){
alert('jpg,gif,jpeh,png 파일만 업로드 할 수 있습니다.');
return fase;
}
}
//Swal.fire("댓글의 길이가 짧습니다", "댓글은 10글자 이상이어야 합니다.", "waring");
}
</script>
메뉴> 갤러리 추가
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav text-uppercase ms-auto py-4 py-lg-0">
<li class="nav-item"><a class="nav-link" href="./board">게시판</a></li>
<li class="nav-item"><a class="nav-link" href="./gallery">갤러리</a></li>
<li class="nav-item"><a class="nav-link" href="./file">파일</a></li>
<li class="nav-item"><a class="nav-link" href="./mail">메일</a></li>
<li class="nav-item"><a class="nav-link" href="./notice">공지사항</a></li>
<c:choose>
<c:when test="${sessionScope.mid ne null }">
<li class="nav-item"><a class="nav-link"
href="./myInfo@${sessionScope.mid }">${sessionScope.mname } 님</a></li>
<li class="nav-item"><a class="nav-link" href="./logout">로그아웃</a></li>
</c:when>
<c:otherwise>
<li class="nav-item"><a class="nav-link" href="./login">로그인</a></li>
</c:otherwise>
</c:choose>
갤러리컨트롤러 만들기
package org.mask.controller;
import org.mask.dto.GalleryDTO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class GalleryController {
@GetMapping("/gallery")
public String gallery() {
return "gallery";
}
@PostMapping("/galleryInsert")
public String galleryInset(GalleryDTO dto) {
return "redirect:/gallery";
}
}
갤러리dto 만들기
package org.mask.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class GalleryDTO {
private int gno, glike, gdel;
private String gtitle, gcontent, gfile, gthumbnail, gdate, mname, mid;
}
데이터베이스 만들기
갤러리 DAO
package org.mask.dao;
import org.apache.ibatis.session.SqlSession;
import org.mask.dto.GalleryDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class GalleryDAO {
@Autowired
private SqlSession sqlSession;
public int galleryInsert(GalleryDTO dto) {
return sqlSession.insert("gallery.galleryInsert", dto);
}
}
갤러리 서비스
@Service
public class GalleryService {
@Autowired
private GalleryDAO galleryDAO;
@Autowired
Util util;
public int galleryInsert(GalleryDTO dto) {
//세션 추가
if(util.getSession().getAttribute("mid") != null) {
dto.setMid((String) util.getSession().getAttribute("mid"));
return galleryDAO.galleryInsert(dto);
} else {
return 0;
}
}
갤러리 컨트롤러
package org.mask.controller;
import org.mask.dto.GalleryDTO;
import org.mask.service.GalleryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class GalleryController {
@Autowired
private GalleryService galleryService;
@GetMapping("/gallery")
public String gallery() {
return "gallery";
}
@GetMapping("/galleryInsert")
public String galleryInsert() {
return "galleryInsert";
}
@PostMapping("/galleryInsert")
public String galleryInset(GalleryDTO dto) {
return "redirect:/gallery";
}
}
매퍼
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="gallery">
<insert id="galleryInsert" parameterType="galleryDTO">
INSERT INTO gallery (gtitle, gcontent, gfile, mno) VALUES (#{gtitle},
#{gcontent}, #{gfile}, (SELECT mno FROM member WHERE mid=#{mid}))
</insert>
</mapper>
갤러리JSP,
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Trinity Company - 갤러리</title>
<!-- Favicon-->
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<link rel="shortcut icon" type="image/x-icon" href="assets/favicon.ico" />
<link rel="apple-touch-icon" sizes="57x57" href="assets/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="assets/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="assets/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="assets/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="assets/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="assets/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="assets/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="assets/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="assets/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="assets/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="assets/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon-16x16.png">
<link rel="manifest" href="assets/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<!-- Font Awesome icons (free version)-->
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
<!-- Google fonts-->
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700" rel="stylesheet" type="text/css" />
<!-- Core theme CSS (includes Bootstrap)-->
<link href="css/styles.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script type="text/javascript">
const Toast = Swal.mixin({
toast: true,
position: 'center-center',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
}
</script>
</head>
<body id="page-top">
<!-- Navigation-->
<%@ include file="menu.jsp" %>
<!-- gallery -->
<section class="page-section" id="gallery">
<div class="container">
<div class="text-center">
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>이미지</th>
<th>날짜</th>
<th>좋아요</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list }" var="row">
<tr>
<td>${row.gno }</td>
<td>${row.gtitle }</td>
<td>
<img alt="" src="./upfile/s_${row.gfile }">
</td>
<td>${row.gdate }</td>
<td>${row.glike }</td>
</tr>
</c:forEach>
</tbody>
</table>
<button class="btn btn-outline-secondary" type="submit" onclick="location.href='./galleryInsert'">글쓰기</button>
</div>
</div>
</section>
<!-- Bootstrap core JS-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Core theme JS-->
<script src="js/scripts.js"></script>
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
<!-- * * SB Forms JS * *-->
<!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
<script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script>
</body>
</html>
갤러리인서트 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Trinity Company - 갤러리 게시판 글쓰기</title>
<!-- Favicon-->
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<link rel="shortcut icon" type="image/x-icon" href="assets/favicon.ico" />
<link rel="apple-touch-icon" sizes="57x57" href="assets/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="assets/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="assets/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="assets/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="assets/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="assets/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="assets/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="assets/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="assets/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="assets/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="assets/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon-16x16.png">
<link rel="manifest" href="assets/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<!-- Font Awesome icons (free version)-->
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
<!-- Google fonts-->
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700" rel="stylesheet" type="text/css" />
<!-- Core theme CSS (includes Bootstrap)-->
<link href="css/styles.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script type="text/javascript">
const Toast = Swal.mixin({
toast: true,
position: 'center-center',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
function fileCheck() {
var fileVal = $("#file1").val(); // 파일이름 가져오기
if (fileVal == "") {
alert('파일을 선택하세요.');
return false;
} else {
var ext = fileVal.split('.').pop().toLowerCase(); //확장자분리
//아래 확장자가 있는지 체크
if ($.inArray(ext, ['jpg', 'jpeg', 'gif', 'png']) == -1) {
alert('jpg,gif,jpeg,png 파일만 업로드 할 수 있습니다.');
return false;
}
}
//Swal.fire("댓글의 길이가 짧습니다","댓글은 10글자 이상이어야 합니다.", "warning");
}
</script>
</head>
<body id="page-top">
<!-- Navigation-->
<%@ include file="menu.jsp" %>
<!-- 갤러리 글쓰기 -->
<section class="page-section" id="gallery">
<div class="container">
<div class="text-center">
<h1 class="mt-5">갤러리 글쓰기</h1>
<form action="./galleryInsert" method="post" enctype="multipart/form-data" onsubmit="return fileCheck()">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon3">제목</span>
<input type="text" name="gtitle" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
<div class="input-group mb-3" style="height: 300px;">
<span class="input-group-text">내용</span>
<textarea class="form-control" aria-label="With textarea" name="gcontent"></textarea>
</div>
<div class="input-group mb-3">
<input type="file" accept="image/*" id="file1" name="file1" class="form-control">
</div>
<div class="input-group mb-3">
<button class="btn btn-outline-secondary" type="submit">업로드</button>
</div>
</form>
</div>
</div>
</section>
<!-- Bootstrap core JS-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Core theme JS-->
<script src="js/scripts.js"></script>
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
<!-- * * SB Forms JS * *-->
<!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
<script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script>
</body>
</html>
갤러리 jsp 꾸며주기.
화면에 띄우게 해보기
갤러리컨트롤러
@PostMapping("/galleryInsert")
public String galleryInset(GalleryDTO dto) {
System.out.println(dto.getGtitle());
System.out.println(dto.getGcontent());
int result = galleryService.galleryInsert(dto);
return "redirect:/gallery";
}
디비에 실제로 저장되기 수정된 부분이 많으니까 자세히 살펴보기
갤러리컨트롤러>유틸 fileUpload 추가
//파일 업로드 -> util
String newFileName = util.fileUpload(upFile);
dto.setGfile(upFile.getOriginalFilename());
int result = galleryService.galleryInsert(dto);
return "redirect:/gallery";
유틸> fileUpload 추가
public String fileUpload(MultipartFile upFile) {
//경로 저장
String root = req().getSession().getServletContext().getRealPath("/");
String upfilePath = root + "resources\\upfile\\";
//UUID
UUID uuid = UUID.randomUUID();
//uuid를 포함한 파일명
String newFileName = uuid.toString()+ upFile.getOriginalFilename();
//실제 업로드
File file = new File(upfilePath, newFileName);
if(file.exists() == false) {
file.mkdirs();//경로가 없다면 다 만들어주기.
}
try {
FileOutputStream thumbnail = new FileOutputStream(new File(upfilePath, "s_"+newFileName));
Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail,100, 100 );
thumbnail.close();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return newFileName;
}
여기까지 잘 됐으면, 데이터베이스에 저장도 되고, 실제 경로에도 저장이 되면 된다.
화면에 띄우기
갤러리 컨트롤러 > @GetMapping("/gallery") 수정
@GetMapping("/gallery")
public String gallery(Model model) {
List<GalleryDTO> list = galleryService.galleryList();
model.addAttribute("list", list);
return "gallery";
}
갤러리 서비스>
public List<GalleryDTO> galleryList() {
return galleryDAO.galleryList();
}
갤러리 다오>
public List<GalleryDTO> galleryList() {
return sqlSession.selectList("gallery.galleryList");
}
매퍼
갤러리jsp
<!-- 갤러리 글쓰기 -->
<section class="page-section" id="gallery">
<div class="d-flex justify-content-center">
<div class="text-center">
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>이미지</th>
<th>날짜</th>
<th>좋아요</th>
</tr>
</thead>
<tbody>
<c:forEach items="${lis }" var="row>">
<tr>
<td>${row.gno }</td>
<td>${row.gtitle }</td>
<td>${row.gno }</td>
<td>
<img alt="" src="./upfile/s_${row.gfile }">
</td>
<td>${row.gdate }</td>
<td>${row.glike }</td>
<tr>
</c:forEach>
</tbody>
</table>
아래처럼 나오면 된다.
'2023.11.21-2024.05.31' 카테고리의 다른 글
20240227 스프링(공지 게시판) (1) | 2024.02.27 |
---|---|
20240226 스프링(갤러리 상세보기(detail), 갤러리 컨트롤러/서비스 상속만들기 , 공지게시판) (1) | 2024.02.26 |
20240222 스프링(요구사항 확인-읽음 수 올리기,파일업로드, 디비 암호화) (0) | 2024.02.22 |
20240221 스프링(로그인-글쓰기 버튼, 댓글쓰기, 수정,삭제, ip) (0) | 2024.02.21 |
20240221 스프링(글쓰기, 댓글쓰기 ip, 엔터키처리) (1) | 2024.02.21 |