210422 TIL (D+71 μŠ€ν”„λ§ File μ—…λ‘œλ“œ, λ‹€μš΄λ‘œλ“œ κ΅¬ν˜„)

2021. 4. 22. 17:57Β·πŸ’» 개발/πŸ“– TIL (Today I Learned)

이전 μ΄ν΄λ¦½μŠ€μ—μ„œ Model1 λ°©μ‹μœΌλ‘œ λ§Œλ“€μ—ˆλ˜ 파일 μ—…λ‘œλ“œ κ΅¬ν˜„μ„ μŠ€ν”„λ§μ—μ„œ λ‹€μ‹œ ν•΄λ³΄μ•˜λ‹€.

이전보닀 κ°„νŽΈν•΄μ§„ 점은 μ»¨νŠΈλ‘€λŸ¬μ—μ„œ MultipartFile μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 λ§€κ°œλ³€μˆ˜λ‘œ file form을 μ‰½κ²Œ λ”°λ‘œ 받을 수 μžˆλ‹€λŠ” 것.

 

 

 


κΈ°λ³Έ μ„ΈνŒ…

 

1. 메이븐 λ ˆνŒŒμ§€ν† λ¦¬μ—μ„œ fileupload 검색

2. Apache Commons FileUpload의 maven νƒœκ·Έ κ°€μ Έμ™€μ„œ pom.xml에 μž‘μ„± (μ•„λž˜ νƒœκ·Έ)

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
	<dependency>
	    <groupId>commons-fileupload</groupId>
	    <artifactId>commons-fileupload</artifactId>
	    <version>1.3.3</version>
	</dependency>

3. /spring 폴더에 file-context.xml μž‘μ„±

 

 

file-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

	<!-- upload -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="104857600"/> <!-- ν•œ μš”μ²­λ‹Ή ν—ˆμš©λ˜λŠ” μ΅œλŒ€μ‚¬μ΄μ¦ˆ 100mb -->
		<property name="maxInMemorySize" value="102400"/>
		<property name="defaultEncoding" value="UTF-8" />
		<property name="uploadTempDir" value="upload" />
	</bean>
	
	
	<!-- download -->
	<bean id="downloadView" class="util.DownloadView"/>
	
	<bean id="downloadViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<property name="order">
			<value>0</value>
		</property>
	</bean>

</beans>

 

5. web.xml에 xml 경둜 μΆ”κ°€

 

  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
	      /WEB-INF/spring/servlet-context.xml
	      /WEB-INF/spring/aop-context.xml
	      /WEB-INF/spring/file-context.xml	<!--μ—¬κΈ° 좔가됨 -->
      </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

 

6. ν…Œμ΄λΈ” 생성

 

DROP TABLE PDS
CASCADE CONSTRAINTS;

DROP SEQUENCE SEQ_PDS;

-----------------------

CREATE TABLE PDS(
   SEQ NUMBER(8) PRIMARY KEY,
   ID VARCHAR2(50) NOT NULL,
   TITLE VARCHAR2(200) NOT NULL,
   CONTENT VARCHAR2(4000) NOT NULL,
   FILENAME VARCHAR2(50) NOT NULL,
   NEWFILENAME VARCHAR2(50) NOT NULL,
   READCOUNT NUMBER(8) NOT NULL,
   DOWNCOUNT NUMBER(8) NOT NULL,
   REGDATE DATE NOT NULL
);

CREATE SEQUENCE SEQ_PDS
START WITH 1
INCREMENT BY 1;

ALTER TABLE PDS
ADD CONSTRAINT FK_PDS_ID FOREIGN KEY(ID)
REFERENCES MEMBER(ID);

 


 

PdsController.java

 

package bit.com.a.controller;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import bit.com.a.dto.BbsDto;
import bit.com.a.dto.PdsDto;
import bit.com.a.service.PdsService;
import util.PdsUtil;


@Controller
public class PdsController {

	@Autowired
	PdsService service;
	
	@RequestMapping(value = "pdslist.do", method = {RequestMethod.GET, RequestMethod.POST})
	public String pdslist(Model model) {
		model.addAttribute("doc_title", "μžλ£Œμ‹€ λͺ©λ‘");
		
		List<PdsDto> list = service.getPdsList();
		model.addAttribute("pdslist", list);
		
		
		return "pdslist.tiles";
	}
	
	
	@RequestMapping(value = "pdsWrite.do", method = {RequestMethod.GET, RequestMethod.POST})
	public String pdsWrite(Model model) {
		model.addAttribute("doc_title", "자료 올리기");
		
		return "pdsWrite.tiles";
	}
	
	
	//μ—…λ‘œλ“œ
	@RequestMapping(value = "pdsUpload.do", method = {RequestMethod.GET, RequestMethod.POST})
	public String pdsUpload(PdsDto pdsdto, @RequestParam(value="fileload", required = false) MultipartFile fileload,
								HttpServletRequest req) {
		
		PdsUtil.fileUpload(pdsdto, fileload, req);
		
		//DBμ €μž₯
		service.uploadPds(pdsdto);
		
		return "redirect:/pdslist.do";
	}
	
	@RequestMapping(value = "fileDownload.do", method = {RequestMethod.GET, RequestMethod.POST})
	public String fileDownload(String newFilename, int seq, HttpServletRequest req, Model model) {
		
		
		/* download 경둜 μ„€μ • */
		// 1. server
		String fupload = req.getServletContext().getRealPath("/upload");
		
		// 2. folder
//		String fupload = "d:\\tmp";
		
		File downloadFile = new File(fupload + "/" + newFilename);
		
		model.addAttribute("downloadFile", downloadFile);
		model.addAttribute("seq", seq);
		
		return "downloadView";
	}
	
	
	@RequestMapping(value = "pdsDetail.do", method = { RequestMethod.GET, RequestMethod.POST })
	public String pdsDetail(Model model, Integer seq, HttpServletRequest req) {
		
		if(seq == null) seq = -1;
		
		service.readCount(seq);
		PdsDto dto = service.getDetail(seq);
		
		model.addAttribute("pds", dto);
		model.addAttribute("doc_title", "κΈ€ μƒμ„ΈνŽ˜μ΄μ§€");
		return "pdsDetail.tiles";
	}
	
	
	
	@RequestMapping(value = "pdsDelete.do", method = { RequestMethod.GET, RequestMethod.POST })
	public String pdsDelete(Model model, Integer seq) {
		
		if(seq == null) seq = -1;
		
		boolean b = service.deletePds(seq);
		
		if(b) {
			System.out.println("μ‚­μ œ 성곡");
		} else {
			System.out.println("μ‚­μ œ μ‹€νŒ¨");
		}
		
		return "redirect:/pdslist.do";
		
	}
	
	
	@RequestMapping(value = "pdsUpdate.do", method = { RequestMethod.GET, RequestMethod.POST })
	public String pdsUpdate(Model model, Integer seq) {
		
		if(seq == null) seq = -1;
		PdsDto dto = service.getDetail(seq);
		model.addAttribute("pds", dto);
		model.addAttribute("doc_title", "κΈ€μˆ˜μ •");
		return "pdsUpdate.tiles";
	}
	
	
	@RequestMapping(value = "pdsUpdateAf.do", method = {RequestMethod.GET, RequestMethod.POST})
	public String pdsUpdateAf(PdsDto pdsdto, @RequestParam(value="fileload", required = false) MultipartFile fileload,
								HttpServletRequest req) {
		
		System.out.println("νŒŒμΌλ“€μ–΄μ™”λŠ”μ§€ μ•ˆλ“€μ–΄μ™”λŠ”μ§€. λ“€μ–΄μ˜€λ©΄ true: "+!fileload.isEmpty());
		
		if(!fileload.isEmpty()) {
			PdsUtil.fileUpload(pdsdto, fileload, req);
		}
		
		System.out.println("μˆ˜μ •μ‚¬ν•­ :" +pdsdto.toString());
		boolean b = service.updatePds(pdsdto);
		
		if(b) {
			System.out.println("μˆ˜μ • 성곡");
		} else {
			System.out.println("μˆ˜μ • μ‹€νŒ¨");
		}
		
		return "redirect:/pdslist.do";
	}	
	
}

 

 

PdsUtil.java

 

μ—…λ‘œλ“œ κ΄€λ ¨ 클래슀.

μ„œλ²„ λ˜λŠ” 디렉토리에 μ €μž₯될 파일의 이름 쀑볡 제거λ₯Ό μœ„ν•΄ ν˜„μž¬ μ‹œκ°„μœΌλ‘œ 파일 이름을 λ°”κΎΈλŠ” μž‘μ—…μ„ ν•œλ‹€.

MultipartFile μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 파일 μ—…λ‘œλ“œ κ΅¬ν˜„.

μ•„λž˜λŠ” 파일 μ΄λ¦„μ—μ„œ '.'의 μœ„μΉ˜λ₯Ό μ•žμ—μ„œλΆ€ν„° κ΅¬ν–ˆμ§€λ§Œ 파일자체 이름에 '.'이 포함될 수 μžˆμœΌλ―€λ‘œ,

lastIndexOf('.')λ₯Ό ν†΅ν•˜μ—¬ κ΅¬ν˜„ν•˜λŠ”κ²Œ λ°”λžŒμ§ν•˜λ‹€.

 

package util;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import bit.com.a.dto.PdsDto;

public class PdsUtil {

	/* 파일λͺ… λ³€κ²½(time) */
	// ex) myfile.txt --> 2646718454.txt
	
	
	// myfile.txt -> indexOf('.') -> 6
	// '.'의 μœ„μΉ˜λ₯Ό κ΅¬ν•˜μ—¬ 파일λͺ…, ν™•μž₯자λͺ… λ‚˜λˆˆλ‹€.
	// substring(0, 6) -> 파일λͺ…. 0λΆ€ν„° 6 μ „κΉŒμ§€
	// substring(6) -> ν™•μž₯자λͺ…(.txt). 6λΆ€ν„° λκΉŒμ§€
	
	public static String getNewFileName(String f) {
		String filename = "";
		String fpost = "";
		
		if(f.indexOf('.') >= 0) {	// λ„νŠΈκ°€ μžˆμ„ λ•Œ(ν™•μž₯자λͺ…이 μžˆμ„λ•Œ),
			fpost = f.substring(f.indexOf('.'));	//ν™•μž₯자λͺ… (.txt)
			filename = new Date().getTime() + fpost;
		}
		else {
			filename = new Date().getTime()+ ".back";	//μž„μ˜μ˜ ν™•μž₯자λͺ…을 λΆ™μ—¬λ‘ 
		}
		
		return filename;
	}
	
	
	public static PdsDto fileUpload(PdsDto pdsdto, MultipartFile fileload, HttpServletRequest req) {
		
		/* filename 취득 */
		String filename = fileload.getOriginalFilename();
		pdsdto.setFilename(filename);	//원본 파일λͺ…
		
		/* upload 경둜 μ„€μ • */
		// 1. server(tomcat)
		String fupload = req.getServletContext().getRealPath("/upload");
		
		// 2. folder(디렉토리)
//		String fupload = "d:\\tmp";
		
		System.out.println("경둜 : "+fupload);
		
		/* 파일λͺ… λ³€κ²½ */
		String newFilename = PdsUtil.getNewFileName(pdsdto.getFilename());
		pdsdto.setNewFilename(newFilename);
		
		
		File file = new File(fupload + "/" + newFilename);	// c:~~/~~/43253244214.jpg
		//import org.apache.commons.io.FileUtils;
		try {
			//μ‹€μ œ μ—…λ‘œλ“œ λ˜λŠ” λΆ€λΆ„
			FileUtils.writeByteArrayToFile(file, fileload.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return pdsdto;
	}
	
}

 

 

pdslist.jsp

 

메인 리슀트 νŽ˜μ΄μ§€.

 

 

β€» λ‹€μš΄λ‘œλ“œ λ²„νŠΌ κ΅¬ν˜„ μ‹œ POST둜 보내야 ν•  λ•Œ

hidden input을 κ°€μ§€κ³  μžˆλŠ” form을 λ§Œλ“€μ–΄ μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜λ₯Ό 톡해 submitν•œλ‹€.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    
<table class="list_table" style="width:85%">
	<colgroup>
		<col width="50">
		<col width="100">
		<col width="300">
		<col width="50">
		<col width="50">
		<col width="50">
		<col width="100">
		<col width="50">
	</colgroup>
	<thead>
		<tr>
			<th>번호</th>
			<th>μž‘μ„±μž</th>
			<th>제λͺ©</th>
			<th>λ‹€μš΄λ‘œλ“œ</th>
			<th>쑰회수</th>
			<th>λ‹€μš΄λ‘œλ“œμˆ˜</th>
			<th>μž‘μ„±μΌ</th>
			<th>μ‚­μ œ</th>
		</tr>	
	</thead>
	<tbody>
		<c:forEach var="pds" items="${pdslist }" varStatus="i">
			<tr>
				<th>${i.count }</th>
				<td>${pds.id }</td>
				<td style="text-align: left;"><a href="pdsDetail.do?seq=${pds.seq}">${pds.title }</a></td>
				<td><input type="button" name="btnDown" value="λ‹€μš΄λ‘œλ“œ" onclick="fileDown('${pds.newFilename}','${pds.seq }')"></td>
				<td>${pds.readcount }</td>
				<td>${pds.downcount }</td>
				<td><font size="1">${pds.regdate }</font></td>
				<td><img alt="" src="image/del.png" data_file_seq="${pds.seq }" class="btn_fileDelete" onclick="deletePage(${pds.seq })"></td>
			</tr>
		</c:forEach>
	</tbody>
</table>



<div id="button.wrap">
	<span class="button blue">
		<button type="button" id="_btnAdd">μžλ£ŒμΆ”κ°€</button>
	</span>
</div>



<!-- λ‹€μš΄λ‘œλ“œ λ²„νŠΌ 클릭 -->
<form name="file_Down" action="fileDownload.do" method="post">
	<input type="hidden" name="newFilename">
	<input type="hidden" name="seq">
</form>


<script>

	$('#_btnAdd').click(function() {
		location.href = "pdsWrite.do";
	});
	

/* hidden form을 λ§Œλ“€μ–΄ POST λ°©μ‹μœΌλ‘œ 전달할 수 μžˆλ‹€. (JSλŠ” 기본적으둜 GETλ°©μ‹λ§Œ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έ)*/
function fileDown(newFilename, seq) {
	let doc = document.file_Down;
	doc.newFilename.value = newFilename;
	doc.seq.value = seq;
	doc.submit();
}	
	
	
function deletePage(seq) {
	 if (confirm("정말 μ‚­μ œν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?") == true){    //확인
		 location.href="pdsDelete.do?seq="+seq;
	 }else{   //μ·¨μ†Œ
	     return false;
	 }
}	

	
</script>

 

 

pds.xml

 

DB μ ‘κ·Ό Mybatis mapper

<?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="Pds">

<select id="getPdsList" resultType="bit.com.a.dto.PdsDto">
	SELECT SEQ, ID, TITLE, CONTENT, FILENAME, NEWFILENAME, READCOUNT, DOWNCOUNT, REGDATE
	FROM PDS
	ORDER BY SEQ DESC	
</select>


<insert id="uploadPds" parameterType="bit.com.a.dto.PdsDto">
	INSERT INTO PDS(SEQ, ID, TITLE, CONTENT, FILENAME, NEWFILENAME, READCOUNT, DOWNCOUNT, REGDATE)
	VALUES (SEQ_PDS.NEXTVAL, #{id}, #{title}, #{content}, #{filename}, #{newFilename}, 0, 0, SYSDATE)
</insert>



<!-- μ˜€λ¦¬μ§€λ‚  이름 κ°€μ Έμ˜€κΈ° -->
<select id="getFilename" parameterType="string" resultType="string">
	SELECT FILENAME
	FROM PDS
	WHERE NEWFILENAME=#{newFilename}
</select>


<!-- 쑰회수 증가 -->
<update id="readCount" parameterType="int">
	UPDATE PDS
	SET READCOUNT = READCOUNT + 1
	WHERE SEQ=#{seq}
</update>	

<!-- λ‹€μš΄λ‘œλ“œμˆ˜ 증가 -->
<update id="downloadCount" parameterType="int">
	UPDATE PDS
	SET DOWNCOUNT = DOWNCOUNT + 1
	WHERE SEQ=#{seq}
</update>	


<!-- λ””ν…ŒμΌ -->
<select id="getDetail" parameterType="int" resultType="bit.com.a.dto.PdsDto">
	SELECT SEQ, ID, TITLE, CONTENT, FILENAME, NEWFILENAME, READCOUNT, DOWNCOUNT, REGDATE
	FROM PDS
	WHERE SEQ=#{seq}
</select>


<!-- μ‚­μ œ -->
<delete id="delete" parameterType="int">
	DELETE FROM PDS
	WHERE SEQ=#{seq}
</delete>


<!-- κΈ€μˆ˜μ • -->
<update id="update" parameterType="bit.com.a.dto.PdsDto">
	UPDATE PDS 
	SET TITLE=#{title}, CONTENT=#{content}
	<if test="filename != null and filename != '' and newFilename != null and newFilename != '' ">	
		, FILENAME=#{filename}, NEWFILENAME=#{newFilename}
	</if>		
	WHERE SEQ=#{seq}
</update>



</mapper>  

 

μ €μž‘μžν‘œμ‹œ (μƒˆμ°½μ—΄λ¦Ό)

'πŸ’» 개발 > πŸ“– TIL (Today I Learned)' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

210427 TIL(D+74 μŠ€ν”„λ§ νˆ¬ν‘œ κ΅¬ν˜„, Crawling, μ»€μŠ€ν…€ μ–΄λ…Έν…Œμ΄μ…˜ ν™œμš©ν•œ AOP, μ›Ή μ†ŒμΌ“)  (0) 2021.04.27
ajax ν™œμš© μΊ˜λ¦°λ” λ§Œλ“€κΈ°  (1) 2021.04.21
'πŸ’» 개발/πŸ“– TIL (Today I Learned)' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • 210427 TIL(D+74 μŠ€ν”„λ§ νˆ¬ν‘œ κ΅¬ν˜„, Crawling, μ»€μŠ€ν…€ μ–΄λ…Έν…Œμ΄μ…˜ ν™œμš©ν•œ AOP, μ›Ή μ†ŒμΌ“)
  • ajax ν™œμš© μΊ˜λ¦°λ” λ§Œλ“€κΈ°
EastShine_
EastShine_
더 λ‚˜μ€ κ°œλ°œμžκ°€ 되기 μœ„ν•œ λ‚˜μ˜ 기둝 πŸ“
  • EastShine_
    개발.LOG πŸ’»
    EastShine_
  • 전체
    였늘
    μ–΄μ œ
  • 05-24 12:18
    • λΆ„λ₯˜ 전체보기 (27)
      • πŸ’» 개발 (21)
        • πŸ–₯️ 운영체제 (3)
        • 🌏 λ„€νŠΈμ›Œν¬ (0)
        • πŸ’Ύ Database (3)
        • πŸŽ› Java (0)
        • πŸ–² Javascript (0)
        • πŸ€ Spring (5)
        • 🎸 ETC (4)
        • πŸ“ˆ μ•Œκ³ λ¦¬μ¦˜ (3)
        • πŸ“– TIL (Today I Learned) (3)
      • 🏠 일상 (6)
        • πŸ““ 일상 일기 (6)
  • 인기 κΈ€

  • νƒœκ·Έ

    낙관적락
    Whisper API
    νŠΈλžœμž­μ…˜ 뢄리
    ν•­ν•΄ν”ŒλŸ¬μŠ€
    transactionaleventlistener
    μ•Œκ³ λ¦¬μ¦˜
    ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€
    6κΈ°
    λŒ€κΈ°μ—΄
    Python
    redis
    μ½˜μ„œνŠΈμ˜ˆμ•½μ„œλΉ„μŠ€
    spring
    λ°±μ—”λ“œ
    λ™μ‹œμ„±μ²˜λ¦¬
    회고
    비관적락
    e-book pdf λ³€ν™˜
    μ½”λ”©ν…ŒμŠ€νŠΈ
    e-book pdf μΆ”μΆœ
  • 졜근 λŒ“κΈ€

  • 졜근 κΈ€

  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.1
EastShine_
210422 TIL (D+71 μŠ€ν”„λ§ File μ—…λ‘œλ“œ, λ‹€μš΄λ‘œλ“œ κ΅¬ν˜„)
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”