<table생성>
-메인 파일 업로드 테이블
-서브 파일 업로드 테이블
create table tbl_file(
fileName varchar(200) primary key,
code int,
regdate datetime default now(),
foreign key(code) references tbl_product(code)
);
-메인 파일 업로드 테이블
>ProductVO
package com.example.domain;
import java.util.Arrays;
public class ProductVO {
private int code;
private String pname;
private int price;
private String image;
private String[] files;
public String[] getFiles() {
return files;
}
public void setFiles(String[] files) {
this.files = files;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
return "ProductVO [code=" + code + ", pname=" + pname + ", price=" + price + ", image=" + image + ", files="
+ Arrays.toString(files) + "]";
}
}
>ProductDAO
<?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="ProductMapper">
<insert id="insert">
insert into tbl_product(pname,price,image)
values(#{pname},#{price},#{image})
</insert>
<select id="list" resultType="com.example.domain.ProductVO">
select * from tbl_product
</select>
<select id="read" resultType="com.example.domain.ProductVO">
select * from tbl_product
where code=#{code}
</select>
<delete id="delete">
delete from tbl_product
where code=#{code}
</delete>
<insert id="addAttach">
insert into tbl_file(fileName,code)
values(#{fullName},last_insert_id());
</insert>
<select id="getAttach" resultType="string">
select fileName from tbl_file
where code=#{code}
</select>
</mapper>
>ProductDAOImpl
package com.example.persistence;
import java.util.List;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.example.domain.ProductVO;
@Repository
public class ProductDAOImpl implements ProductDAO{
@Inject
SqlSession session;
String namespace="ProductMapper";
@Override
public void insert(ProductVO vo) {
session.insert(namespace+".insert",vo);
}
@Override
public List<ProductVO> list() {
// TODO Auto-generated method stub
return session.selectList(namespace+".list");
}
@Override
public ProductVO read(int code) {
// TODO Auto-generated method stub
return session.selectOne(namespace+".read",code);
}
@Override
public void delete(int code) {
// TODO Auto-generated method stub
session.delete(namespace+".delete",code);
}
@Override
public void addAttach(String fullName) {
// TODO Auto-generated method stub
session.insert(namespace +".getAttach",fullName);
}
@Override
public List<String> getAttach(int code) {
return session.selectList(namespace+".getAttach",code);
}
}
>ProductController
package com.example.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.example.domain.ProductVO;
import com.example.persistence.ProductDAO;
import com.example.service.ProductService;
@Controller
public class ProductController {
@Resource(name = "uploadPath")
private String path;
@Inject
ProductDAO dao;
@Inject
ProductService service;
@RequestMapping("insert")
public String insert() {
return "insert";
}
@RequestMapping("list")
public String list(Model model) {
model.addAttribute("list",dao.list());
return "list";
}
@RequestMapping("read")
public String read(Model model,int code){
model.addAttribute("vo",dao.read(code));
return "read";
}
@ResponseBody//AJAX으로 파일업로드
@RequestMapping(value="upload",method=RequestMethod.POST,produces="text/plain;charset=UTF-8")
public String upload(MultipartFile file)throws Exception{
return uploadFile(file.getOriginalFilename(),file.getBytes(),"/sub");
}
@RequestMapping(value = "insert", method = RequestMethod.POST)//form 으로 파일 업로드
public String insertPost(ProductVO vo,MultipartFile file)throws Exception { // ProductVO를 insert하기 전에 파일 업로드
String savedName=uploadFile(file.getOriginalFilename(),file.getBytes(),"");//path에 sub가 없으므로 값을 넣지 않음
vo.setImage(savedName);
//System.out.println("path:" + path);
System.out.println(vo.toString());
service.insert(vo);
//System.out.println("savedName:"+savedName);
return "redirect:list";
}
private String uploadFile(String originalName, byte[] fileData,String sub) throws Exception {//파일업로드 메소드
// 이름을 유니크하게 만드는 함수
UUID uid = UUID.randomUUID();
String savedName = uid.toString() + "-" + originalName;
File target = new File(path+sub, savedName);
FileCopyUtils.copy(fileData, target);
return savedName;
}
@ResponseBody//이미지 파일 출력 메서드
@RequestMapping("display") //server.xml을 수정하지 않고 이미지가 잘 출력됨.
public byte[] display(String fileName)throws Exception{
InputStream in=new FileInputStream(path +"/"+fileName);
return IOUtils.toByteArray(in);
}
@ResponseBody
@RequestMapping(value="deleteFile",method=RequestMethod.POST) //AjAX으로 파일 삭제
public void deleteFile(String fileName){
new File(path , fileName).delete();
//dao.delete(code);
}
@ResponseBody
@RequestMapping("getAttach")
public List<String> getAttach(int code){
//System.out.println(dao.getAttach(code));
return dao.getAttach(code);
}
@ResponseBody
@RequestMapping(value="download",method=RequestMethod.POST)
public void download(String fileName)throws Exception{
InputStream in=new FileInputStream(path +"/"+fileName);
File target= new File("c:/temp",fileName);
FileCopyUtils.copy(IOUtils.toByteArray(in),target);
}
@ResponseBody
@RequestMapping(value="downloadFile")
public ResponseEntity<byte[]> downloadFile(String fileName)throws Exception{
System.out.println("파일이름:" + fileName);
ResponseEntity<byte[]> entity=null;
InputStream in = null;
try{
HttpHeaders headers = new HttpHeaders();
in= new FileInputStream(path + "/" + fileName);
fileName = fileName.substring(fileName.indexOf("_") + 1);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.add("Content-Disposition", "attachment;filename=\"" +
new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"");
entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
}catch(Exception e){
System.out.println(e.toString());
entity= new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
}finally{
in.close();
}
return entity;
}
}
>ProductService
package com.example.service;
import com.example.domain.ProductVO;
public interface ProductService {
public void insert(ProductVO vo);
}
>ProductServiceImpl
package com.example.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.domain.ProductVO;
import com.example.persistence.ProductDAO;
@Service
public class ProductServiceImpl implements ProductService{
@Inject
ProductDAO dao;
@Transactional
@Override
public void insert(ProductVO vo) {
dao.insert(vo);
String[] files=vo.getFiles();
if(files == null) return;
for(String fullName:files){
dao.addAttach(fullName);
}
}
}
>list.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2 style="text-align:center">List</h2>
<div style="text-align:center; margin-bottom:20px;">
<button onClick="location.href='insert'" style="border:none;padding:5px;">상품등록</button>
</div>
<div style="border:1px dotted gray;width:500px; margin:0px auto;">
<c:forEach items="${list}" var="vo">
<div style="text-align:center;float:left;overflow:hidden;padding:5px;margin:5px auto;margin-left:25px;">
<img src="display?fileName=${vo.image}" width=120 onClick="location.href='read?code=${vo.code}'">
<div>상품명:${vo.pname}</div>
<div>상품가격:${vo.price}</div>
</div>
</c:forEach>
</div>
</body>
</html>
insert.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style>
table{
border-top:1px solid gray;
}
td{
border-bottom:1px dotted gray;
padding:5px;
}
</style>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.js"></script>
</head>
<body>
<h2 style="text-align:center;">Product Insert</h2>
<div style="text-align:center; margin-bottom:20px;">
<button onClick="location.href='list'" style="border:none;padding:5px;">상품목록</button>
</div>
<form name="frm" action="insert" method="post" encType="multipart/form-data">
<table border=0 width=600 style="margin:0px auto;text-align:center;">
<tr>
<td>상품명:</td>
<td><input type="text" name="pname"></td>
</tr>
<tr>
<td>상품가격:</td>
<td><input type="text" name="price"></td>
</tr>
<tr>
<td>상품이미지:</td>
<td><input type="file" name="file" style="border:none;padding:10px;"></td>
</tr>
</table>
<div style="text-align:center;margin-top:10px;">
<input type="submit" value="저장" style="border:none; padding:5px;"/>
<input type="reset" value="취소" style="border:none; padding:5px;"/>
</div>
<!-- 업로드할 파일목록 -->
<div style="margin:0px auto; margin-top:10px;width:580px;border:1px solid gray;padding:5px;">
<input type="file" id="file">
</div>
<!-- 업로드한 파일목록 -->
<div style="margin:0px auto; margin-top:10px;width:580px;border:1px solid gray;padding:5px;">
<ul id="uploadedFiles"></ul>
<script id="temp" type="text/x-handlebars-template">
<li>
{{fileName}}
<a href="{{fullName}}"><b>x</b></a>
<input type="text" name="files" value="{{fullName}}">
</li>
</script>
</div>
</form>
</body>
<script>
//파일업로드
$("#file").on("change",function(){
var file=$("#file")[0].files[0];
var formData = new FormData();
formData.append("file",file);
$.ajax({
type:"post",
url:"upload",
data:formData,//multiparttype이기 때문
processData:false,
contentType:false,
success:function(data){
var temp=Handlebars.compile($("#temp").html());
tempData = {"fileName":file.name,"fullName":data};
$("#uploadedFiles").append(temp(tempData));
}
});
});
$("#uploadedFiles").on("click","li a",function(e){
e.preventDefault();//a태그 동작 금지
var that=$(this);
if(!confirm("삭제하시겠습니까?")) return;
var fileName="/sub/" + $(this).attr("href");
$.ajax({
type:"post",
url:"deleteFile",
data:{"fileName":fileName},
success:function(){
alert("삭제");
that.parent().remove();
}
});
});
</script>
</html>
>read.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.js"></script>
<style>
table {
border-top: 1px solid gray;
}
td {
border-bottom: 1px dotted gray;
padding: 5px;
}
</style>
</head>
<body>
<h2 style="text-align: center;">Product Read</h2>
<form name="frm">
<input type="hidden" value="${param.code}" />
<table border=0
style="margin: 0px auto; text-align: center; width: 400px;">
<tr>
<td>상품명:</td>
<td>${vo.pname}</td>
</tr>
<tr>
<td>상품가격:</td>
<td>${vo.price}</td>
</tr>
<tr>
<td colspan=2>
<img src="display?fileName=${vo.image}" width=160px; style="padding: 10px;">
</td>
</tr>
</table>
<div style="text-align: center; margin-bottom: 20px; margin-top: 20px;">
<input type="button" onClick="location.href='list'" value="목록"style="border: none; padding: 5px;">
<input type="button" value="삭제" style="border: none; padding: 5px;" />
<input type="reset" value="취소" style="border: none; padding: 5px;" />
</div>
</form>
<!-- 파일첨부 -->
<!-- 업로드 결과 -->
<div style="border: 2px solid black; width: 400px; margin: 0px auto; margin-top: 20px;">
<ul id="uploaded"></ul>
<script id="temp" type="text/x-handlebars-template">
<li>
<a href="downloadFile?fileName={{fullName}}">{{fileName}}</a>
</li>
</script>
</div>
</body>
<script>
var code="${vo.code}";
getAttach();
function getAttach(){
//alert("혹시");
$.ajax({
type:"get",
url:"getAttach",
data:{"code":code},
success:function(data){
alert("성공?");
var temp=Handlebars.compile($("#temp").html());
$(data).each(function(){
var idx=this.indexOf("_")+1;
var fileName=this.substring(idx);
tempData={"fileName":fileName,"fullName":"/sub/" + this};
$("#uploaded").append(temp(tempData));
});
}
});
}
</script>
</html>