더보기
Spring:4 spring(maven project)를 Mybatis, Mysql과 연결하기(환경설정)-1
Spring:5 spring(maven project)기본 스타일 지정하기-2
Spring:6 로그인 회원가입폼 구현 하고 회원가입 DB연결-3
Spring:7 로그인(DB연동), 로그아웃, 회원정보수정(DB연동)-4
Spring:8 아이디 중복검사(ajax 이용)-5
Spring:9 게시판 리스트생성, DB연결, 글등록폼 생성-1
Spring:10 게시판 리스트 글 등록하고 보여주고 조회수증가-2
Spring:11 게시판 리스트 페이징과 검색 기능, 선택 기능 추가-3
Spring:12 게시판 글 수정, 삭제(한 레코드와 여러 레코드) 구현-4
Spring:13 Interceptor(인터셉터)-5
Spring:14 글 내용에서 댓글 등록,수정,삭제 구현(DB설계와연동)-1
Spring:15 자료실(다운로드, 업로드) DB설계, 환경변수설정-1
Spring:5 spring(maven project)기본 스타일 지정하기-2
Spring:6 로그인 회원가입폼 구현 하고 회원가입 DB연결-3
Spring:7 로그인(DB연동), 로그아웃, 회원정보수정(DB연동)-4
Spring:8 아이디 중복검사(ajax 이용)-5
Spring:9 게시판 리스트생성, DB연결, 글등록폼 생성-1
Spring:10 게시판 리스트 글 등록하고 보여주고 조회수증가-2
Spring:11 게시판 리스트 페이징과 검색 기능, 선택 기능 추가-3
Spring:12 게시판 글 수정, 삭제(한 레코드와 여러 레코드) 구현-4
Spring:13 Interceptor(인터셉터)-5
Spring:14 글 내용에서 댓글 등록,수정,삭제 구현(DB설계와연동)-1
Spring:15 자료실(다운로드, 업로드) DB설계, 환경변수설정-1
1. 상단 메뉴의 자료실을 클릭하면 자료실 글 목록(list)을 보인다.
1. data 폴더 안에 dataLibList.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<style>
#dataLibList>li{
float:left;
width:10%;
height:40px;
line-height:40px;
border-bottom:1px solid black;
}
#dataLibList>li:nth-child(5n+2){ /*제목*/
width:60%
}
</style>
<div class="container">
<h1>자료실 목록</h1>
<a href="">글쓰기</a>
<ul id="dataLibList">
<li>번호</li>
<li>제목</li>
<li>작성자</li>
<li>첨부파일</li>
<li>등록일</li>
<li>번호1</li>
<li>제목1</li>
<li>작성자1</li>
<li>첨부파일1</li>
<li>등록일1</li>
</ul>
</div>
2. header.jspf와 연결(맵핑 주소 연결)
<li><a href="${url}/data/dataLibList">자료실</a></li>
//<li><a href="/myappy/data/dataLibList">자료실</a></li>
3. Controller로 주소 맵핑하기
package com.mycampus.myappy.controller;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
//import com.mycampus.myappy.service.DataLibService;
@RestController
public class DataLibController {
//@Autowired
//DataLibService service;
@GetMapping("/data/dataLibList")
public ModelAndView dataLibraryList() {
ModelAndView mav = new ModelAndView();
mav.setViewName("data/dataLibList");
return mav;
}
}
2. 자료실 글 등록 폼 만들기(글쓰기를 누르면 글 등록 폼이 보이게 한다.)
dataLibList.jsp
<a href="/myappy/data/dataLibWrite">글쓰기</a>
dataLibWrite.jsp 파일 생성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<style>
#subject{width:99%}
#boardFrm li{
padding:10px 5px;
}
</style>
<script src="//cdn.ckeditor.com/4.17.2/standard/ckeditor.js"></script>
<script>
$(function(){
CKEDITOR.replace("content");
$("#dataLibrary").submit(function(){
if($("#subject").val()==''){
alert("글제목을 입력하세요");
return false;
}
if(CKEDITOR.instances.content.getData() == ''){
alert("글내용을 입력하세요");
return false;
}
// 첨부파일 선택 갯수
let fileCount = 0;
if($("#filename1").val()!=''){ // 파일을 선택했을 경우
fileCount++;
}
if($("#filename2").val()!=''){ // 파일을 선택했을 경우
fileCount++;
}
if(fileCount<1){ // 파일을 안골랐다. 초기값이 0
alert("첨부파일은 반드시 1개이상이어야 합니다.")
return false;
}
});
});
</script>
<div class="container">
<h1>자료실 글 등록 폼</h1>
<!-- 파일 업로드의 기능이 있는 폼은 반드시 enctype속성을 명시하여야 한다. -->
<form method="post" id="dataLibrary" action="/myappy/data/dataWriteOk" enctype="multipart/form-data">
<ul>
<li>제목</li>
<li><input type="text" name="subject" id="subject"/></li>
<li>글 내용</li>
<li><textarea name = "content" id="content"></textarea></li>
<li>첨부파일</li>
<li>
<input type="file" name="filename" id="filename1"/><br/>
<input type="file" name="filename" id="filename2"/>
</li>
<li><input type="submit" value="자료실글 등록"/></li>
</ul>
</form>
</div>
DataLibController
@GetMapping("/data/dataLibWrite")
public ModelAndView dataLibraryWrite() {
ModelAndView mav = new ModelAndView();
mav.setViewName("data/dataLibWrite");
return mav;
}
로그인이 되어 있지 있으면 글쓰기를 못하게 하기 위해서 interceptor에 추가한다.
intercept-context.xml (src > main > webapp > WEB-INF > spring > appServlet)
맨 마지막에 추가한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- Interceptor 처리를 위한 컨트롤러 목록을 등록할 객체를 생성한다.namespaes에서 context, mvc를 추가한다. -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/board/bulletinBrdWrite"/>
<mvc:mapping path="/board/bulletinBrdWriteOk"/>
<mvc:mapping path="/board/boardDelete"/>
<mvc:mapping path="/board/multiChkDel"/>
<mvc:mapping path="/data/dataLibWrite"/>
<bean class="com.mycampus.myappy.interceptor.SigninInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
클라이언트가 업로드를 하면 자동으로 upload 폴더에 저장이 된다. (업로드한 파일이 보고 싶으면 저 경로로 들어가면 된다.) + DB에 저장이 된다.
실제 업로드를 구현할 맵핑 주소는 dataLibWrite.jsp에 있다.
첨부되어있는 파일은 서버로 넘어가야 한다. 첨부파일이 있다면 enctype 꼭 명시해줘야 한다.
<form method="post" id="dataLibrary" action="/myappy/data/dataWriteOk" enctype="multipart/form-data">
3. 자료실 글 등록하기(DB 연결)
제목, 글 내용은 일반 데이터로 request 해서 서버에게 넘겨준다.
DB 등록 중 에러나면 다시 글등록 폼으로 DB등록 중 성공하면 다시 자료실 리스트로 맵핑 주소를 연결한다.
DataLibController
// 글 등록 하고 난 후
@PostMapping("/data/dataWriteOk")
public ResponseEntity<String> dataWriteOk(DataLibVO vo, HttpServletRequest request){
// 제목과 내용을 request한다.(VO안에)
// request로 session에서 아이디 구하기
vo.setUserid((String)request.getSession().getAttribute("logId"));
ResponseEntity<String> entity = null;
HttpHeaders headers = new HttpHeaders(); // 성공, 실패 둘 다 js 파일안에
headers.setContentType(new MediaType("text", "html", Charset.forName("UTF-8")));
// 파일 업로드를 위한 업로드 위치의 절대주소(upload폴더)
String path = request.getSession().getServletContext().getRealPath("/upload");
System.out.println("경로: " + path);
try { // 성공했을 때
// 파일 업로드를 처리하기 위해서는 request객체에서 multipart객체로 형변환 필요함
MultipartHttpServletRequest mp = (MultipartHttpServletRequest)request;
// mp에 파일의 수만큼 multipartfile 객체가 존재하기 때문에 파일의 수만큼 multipartfile의 객체를 가져온다.
// getFiles(String name) : List<MultipartFile>
// String name은 첨부파일의 name(dataLibWrite.jsp에서)
List<MultipartFile> files = mp.getFiles("filename");
System.out.println("업로드 파일 수 : " + files.size());
entity = null;
} catch(Exception e) {
e.printStackTrace();
entity = null;
}
return entity;
}
}
서버를 실행하면 절대 경로가 위에 파일 탐색기를 통해 간 것과 동일한 것을 볼 수 있다.
1. VO에 toString 생성
@Override
public String toString() {
return "userid: " + userid + " " + "subject: " + subject + " " + "content: "
+ content + " " + "filename1: " + filename1 + " " + "filename2: " + filename2;
}
2. Controller 파일명 rename 하기(동일한 파일명일 때 rename 하기)
DataLibController
// 글 등록 하고 난 후
@PostMapping("/data/dataWriteOk")
public ResponseEntity<String> dataWriteOk(DataLibVO vo, HttpServletRequest request){
// 제목과 내용을 request한다.(VO안에)
// request로 session에서 아이디 구하기
vo.setUserid((String)request.getSession().getAttribute("logId"));
ResponseEntity<String> entity = null;
HttpHeaders headers = new HttpHeaders(); // 성공, 실패 둘 다 js 파일안에
headers.setContentType(new MediaType("text", "html", Charset.forName("UTF-8")));
// 파일 업로드를 위한 업로드 위치의 절대주소(upload폴더)
String path = request.getSession().getServletContext().getRealPath("/upload");
System.out.println("경로: " + path);
try { // 성공했을 때
// 파일 업로드를 처리하기 위해서는 request객체에서 multipart객체로 형변환 필요함
MultipartHttpServletRequest mp = (MultipartHttpServletRequest)request;
// mp에 파일의 수만큼 multipartfile 객체가 존재하기 때문에 파일의 수만큼 multipartfile의 객체를 가져온다.
List<MultipartFile> files = mp.getFiles("filename");
System.out.println("업로드 파일 수 : " + files.size());
// null이 아닐 때만 작업한다.(files의 개수만큼 업로드)
if(files!=null) { // if 1
int cnt = 1; // 업로드 순서에 따라 filename1, filename2 파일명을 대입하기 위한 변수
//첨부파일 수 만큼 반복해서 업로드
for(int i=0; i<files.size(); i++) { // for 2
// 1. MultipartFile 객체 얻어오기
MultipartFile mf = files.get(i);
// 2. 업로드한 실제 파일명을 구하기
String originFileName = mf.getOriginalFilename();
System.out.println("originFileName : " + originFileName);
// 3. rename하기(동일한 이름이 존재하면 rename하고 없으면 하지 않음)
// rename이란 동일이름에 (1), (2), 이렇게 붙이는 것
if(originFileName!=null && !originFileName.equals("")) { // if 3
File f = new File(path, originFileName);
// 파일이 존재하는지 확인
// return true -> 파일 존재, false : 파일 존재 xx
if(f.exists()) { // if 4 파일객체가 있으면
for(int renameNum =1; ;renameNum++) { // for 5
// 반복문 때문에 1부터 무제한으로 만들어진다.
// 확장자와 파일을 분리한다.(마지막 점의 위치를 구하기)
int dot = originFileName.lastIndexOf(".");
String fileName = originFileName.substring(0,dot); // 파일명
String ext = originFileName.substring(dot+1); // 확장자
// rename(새로운 이름 짓기)
f = new File(path, fileName+ "(" + renameNum + ")" + ext);
if(!f.exists()) { // 새로 생성된 파일객체가 없으면
originFileName = f.getName(); // 파일명만 구하는게 getName
break;
}
} // for 5 끝
} // if 4 (파일객체가 있는 경우)
// 4. 파일 업로드 구현
try { // mf 객체 안에 업로드하려는 메서드를 사용
mf.transferTo(f); // 실제 업로드가 발생, 업로드한 파일 데이터를 지정한 파일에 저장
}catch(Exception e) {}
// 5. 업로드한(새로운 파일명)파일 VO에 세팅
if(cnt==1) vo.setFilename1(originFileName);
if(cnt==2) vo.setFilename2(originFileName);
cnt++;
}// if 3 // rename하기
}// for 2 //첨부파일 수 만큼 반복해서 업로드
}// if 1 // 업로드 끝
System.out.println(vo.toString());
entity = null;
} catch(Exception e) {
e.printStackTrace();
entity = null;
}
return entity;
}
3. DB 작업하기(DB에 정보를 넣기)
Mapper, DAO, Service, ServiceImpl, Controller 매핑 작성
<?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="com.mycampus.myappy.dao.DataLibDAO">
<insert id="dataInsert">
insert into dataLibrary(userid, subject, content, filename1, filename2)
values(#{userid}, #{subject}, #{content}, #{filename1}, #{filename2})
</insert>
</mapper>
package com.mycampus.myappy.dao;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibDAO {
public int dataInsert(DataLibVO vo); // 파일명, 제목, 글내용 등이 있다.
}
package com.mycampus.myappy.service;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibService {
public int dataInsert(DataLibVO vo);
}
package com.mycampus.myappy.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mycampus.myappy.dao.DataLibDAO;
import com.mycampus.myappy.vo.DataLibVO;
@Service
public class DataLibServiceImpl implements DataLibService {
@Autowired
DataLibDAO dao;
@Override
public int dataInsert(DataLibVO vo) {
return dao.dataInsert(vo);
}
}
Controller(DataLibController)
}// if 1 // 업로드 끝
System.out.println(vo.toString());
// DB등록
service.dataInsert(vo);
// 레코드 추가 성공
String msg = "<script>alert('자료실에 글이 등록되었습니다.');";
msg += "location.href='/myappy/data/dataLibList';</script>";
entity = new ResponseEntity<String>(msg, headers, HttpStatus.OK);
} catch(Exception e) { // 레코드 추가 실패
e.printStackTrace();
// 데이터가 DB에 정상적으로 들어가지 않았다면 이미 upload폴더에 업로드한 파일을 지워야 한다.
// 삭제할 파일명은 vo안에 있다.(vo.filename1과 vo.filename2)
fileDelete(path, vo.getFilename1());
fileDelete(path, vo.getFilename2());
// 메세지
String msg = "<script>alert('자료실에 글 등록이 실패하였습니다.');";
msg += "history.back();</script>";
entity = new ResponseEntity<String>(msg, headers, HttpStatus.BAD_REQUEST);
}
return entity;
}
// 파일 삭제 메서드
// 파일 경로와 파일명을 매개변수로 받아서 지운다.
public void fileDelete(String path, String fileName) {
if(fileName!=null) { //파일명이 존재하면
File file = new File(path, fileName); // 파일 객체 생성
file.delete(); // 파일 내장 메서드
}
}
3. 레코드 전체 선택(레코드 목록 보이기)
Mapper, DAO, Service, ServiceImpl, Controller 매핑 작성
<?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="com.mycampus.myappy.dao.DataLibDAO">
<select id="dataAllSelect" resultType="com.mycampus.myappy.vo.dataLibVO">
select no, userid, subject, data_format(createdate, '%m-%d %H:%i')createdate,
filename1, filename2
from dataLibrary order by no desc
</select>
</mapper>
package com.mycampus.myappy.dao;
import java.util.List;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibDAO {
public List<DataLibVO> dataAllSelect();
}
package com.mycampus.myappy.service;
import java.util.List;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibService {
public List<DataLibVO> dataAllSelect();
}
package com.mycampus.myappy.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mycampus.myappy.dao.DataLibDAO;
import com.mycampus.myappy.vo.DataLibVO;
@Service
public class DataLibServiceImpl implements DataLibService {
@Autowired
DataLibDAO dao;
@Override
public List<DataLibVO> dataAllSelect() {
return dao.dataAllSelect();
}
}
Controller(DataLibController)
mav.addObject("list", service.dataAllSelect( )); 추가하기
// 자료실리스트
@GetMapping("/data/dataLibList")
public ModelAndView dataLibraryList() {
ModelAndView mav = new ModelAndView();
mav.addObject("list",service.dataAllSelect());
mav.setViewName("data/dataLibList");
return mav;
}
디스크 이미지 저장하기
- webapp 폴더 밑에 img 폴더 생성하고 disk.png(이미지) 저장하기
- servlet-context.xml
<resources mapping="/img/**" location="/img/"/>
dataLibList.jsp
<c:forEach var="vo" items="${list}">
<li>${vo.no}</li>
<li><a href="#?no=${vo.no}">${vo.subject}</a></li>
<li>${vo.userid}</li>
<li><!-- 첨부파일 기준 -->
<!-- 첫번째 첨부파일 -->
<a href="/myappy/upload/${vo.filename1}" download>
<img src="/myappy/img/disk.png" title="${vo.filename1}"/></a>
<!-- 두번째 첨부파일 있을 경우 -->
<c:if test="${vo.filename2!=null && vo.filename2!=''}">
<a href="/myappy/upload/${vo.filename2}" download>
<img src="/myappy/img/disk.png" title="${vo.filename2}"/></a>
</c:if>
</li>
<li>${vo.createdate}</li>
</c:forEach>
4. 자료실 글 내용 보기 구현하기
맵핑 주소 정하기(dataLibList.jsp)
<li><a href="/myappy/data/dataLibView?no=${vo.no}">${vo.subject}</a></li>
Mapper, DAO, Service, ServiceImpl, Controller 매핑 작성
<?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="com.mycampus.myappy.dao.DataLibDAO">
</select>
<select id="dataView"resultType="com.mycampus.myappy.vo.DataLibVO">
select no, userid, subject, content, createdate, filename1, filename2
from dataLibrary where no=${param1}
</select>
</mapper>
package com.mycampus.myappy.dao;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibDAO {
public DataLibVO dataView(int no);
}
package com.mycampus.myappy.service;
import com.mycampus.myappy.vo.DataLibVO;
public interface DataLibService {
public DataLibVO dataView(int no);
}
package com.mycampus.myappy.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mycampus.myappy.dao.DataLibDAO;
import com.mycampus.myappy.vo.DataLibVO;
@Service
public class DataLibServiceImpl implements DataLibService {
@Autowired
DataLibDAO dao;
@Override
public DataLibVO dataView(int no) {
return dao.dataView(no);
}
}
Controller(DataLibController)
// 글 내용 보기
@GetMapping("data/dataLibView")
public ModelAndView view(int no) {
ModelAndView mav = new ModelAndView();
mav.addObject("dataLibVO", service.dataView(no));
mav.setViewName("data/dataLibView");
return mav;
}
dataLibView.jsp 파일 생성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<div class="container">
<h1>자료실 글 내용보기</h1>
<ul>
<li>번호 : ${dataLibVO.no}</li>
<li>작성자 : ${dataLibVO.userid}</li>
<li>등록일 : ${dataLibVO.createdate}</li>
<li>제목 : ${dataLibVO.subject}</li>
<li>글내용</li>
<li>${dataLibVO.content}</li>
<li>첨부파일 : <a href="/myappy/upload/${dataLibVO.filename1}" download>${dataLibVO.filename1}</a>
<c:if test="${dataLibVO.filename2!=null && dataLibVO.filename2!=''}">
<a href='myappy/upload/${dataLibVO.filename2}' download>${dataLibVO.filename2}</a>
</c:if>
</li>
</ul>
</div>
'멀티캠퍼스 풀스택 과정 > 백엔드' 카테고리의 다른 글
[Node.js] 2. 모듈 생성하고 사용하기 / 이벤트 모듈 생성하고 사용하기 (0) | 2022.03.30 |
---|---|
[Node.js] 1. 시작하기(서버 만들고 실행해보기) (0) | 2022.03.30 |
Spring:15 자료실(다운로드, 업로드) DB설계, 환경변수설정 -1 (0) | 2022.03.22 |
Spring:14 글 내용에서 댓글 등록,수정,삭제 구현(DB설계와연동)-1 (0) | 2022.03.21 |
Spring:13 Interceptor(인터셉터) -5 (0) | 2022.03.19 |