본문 바로가기
CLASS/SPRING,JSTL

#4-2 / gallery board insert-write (spring + I/O + database)

by hingu 2024. 7. 11.

board 파일 첨부시

파일 저장 후에 ===> DB에 저장되어야 함

 

 1. table 만듬

create table gallery(
gidx int(7) not null auto_increment,
gwriter char(100) not null,
gsubject varchar(200) not null,
gtext text not null,
gorifile text null, //사용자가 업로드한 파일명 
gfile text null, //저장시 랜덤함수를 이용하여 저장된 파일명
gindate timestamp not null default current_timestamp,
primary key(gidx)
);

 

 2. gallery_dao.java 생성 : getter,setter

 

첨부하지 않을경우 , 첨부할 경우 배열 length가 달라질 수 있기 때문에 아예 분리해서 받는게 좋다! => list , view 

package shop;

import java.util.ArrayList;
import java.util.Arrays;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class gallery_dao {
	int gidx;
	String gwriter,gsubject,gtext;
	String gorifile,gfile;
	String gindate;
	
	//list 페이지에서 필요한것만!
	public ArrayList<Object> lists(){ 
		ArrayList<Object> al = new ArrayList<Object>();
		
		al.add(getGidx());
		al.add(getGwriter());
		al.add(getGsubject());
		al.add(getGindate());
		
		//null 삭제 안해줘도댐
		//al.removeAll(Arrays.asList("",null));
		
		return al;
	}
	
	//view 페이지는 전부 다 필요함
	public ArrayList<Object> views(){
		ArrayList<Object> al = new ArrayList<Object>();
		
		al.add(getGidx());
		al.add(getGwriter());
		al.add(getGsubject());
		al.add(getGtext());
		al.add(getGorifile());
		al.add(getGfile());
		al.add(getGindate());
		
		//null 삭제 안해도됨 
		//al.removeAll(Arrays.asList("",null));
		
		return al;
	}
}

 

 

 3. gallery_write.jsp 생성 

 

input type file만  name명을 database colomn명과 동일하게 적용하지 않음! 

<body>
	<form method="post" id="frm" action="./gallery_writeok.do" enctype="multipart/form-data">
		글쓴이 : <input type="text" name="gwriter"><br>
		제목 : <input type="text" name="gsubject"><br>
		내용 : <textarea name="gtext" rows="30" cols="100"></textarea><br>
		첨부파일 : <input type="file" name="files" multiple="multiple"><br><br>
		<input type="button" value="등록" onclick="gallerywrite()">
	</form>
</body>

<script>
	function gallerywrite(){
		frm.submit();
	}
</script>

 

 

 4. shop_main2.java @PostMapping("/gallery_writeok.do") - insert

 

@RequestParam MultipartFile 일 때는 file에대한 Name만 적어줘야함!

public String telok(@RequestParam(defaultValue="N",required = false) String agree,String tel,String email[]) { ~~ }

이거  input type text (String)일 경우는 가능했었음

-> https://dev-eunse.tistory.com/195

 

input type file 저장 방식

  1. module 을 하나만 이용하는 방식 - 요거 해봄
  2. 각각의 module 을 이용하는 방식
/*------ gallery board write -------*/
@PostMapping("/gallery_writeok.do")
public void gallery_writeok(
            @ModelAttribute("ga") gallery_dao dao, 
            @RequestParam("files") MultipartFile files[],
            HttpServletResponse res, 
            HttpServletRequest req
        ) throws Exception {
    res.setContentType("text/html;charset=utf-8");
    String fileck = files[0].getOriginalFilename(); //배열 기준 첫번째꺼 첨부했는지 확인

    file_save fs = new file_save();
    String result = fs.datafile_save(dbInfo,dao,files,req);

    this.pw =res.getWriter();
    if(result=="Y") {
        this.pw.print("<script>"
                + "alert('정상적으로 게시물이 등록 되었습니다.');"
                + "location.href='./gallery.do'"
                + "</script>");
    }else {
        this.pw.print("<script>"
                + "alert('데이터 오류로 게시글이 등록되지 않았습니다.');"
                + "location.href='./gallery.do'"
                + "</script>");
    }
    this.pw.close();
}

 

 

file_save.java = shop_main2.java에서 호출하는 file 저장 module

 

* 해당 모듈 기능 , 순서

  1. 파일명 생성(random함수 이용)
  2. 실제 file => 웹 디렉토리에 저장 
  3. file명 및 경로 => database에저장 
package shop;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

public class file_save {
	Connection con = null;
	PreparedStatement ps = null;
	String result = ""; //결과값 (Y:성공,N:실패)
	
	//파일명 생성 (random함수 이용)
	public String rename() {
		Date day = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
		int no = (int)Math.ceil(Math.random()*1000);
		String today = sf.format(day);
		
		String datacode = today + "_" + no;
		
		return datacode;
	}
	
	//file 저장 및 database에 insert
	public String datafile_save(
				BasicDataSource dbinfo,gallery_dao dao,
				MultipartFile files[],HttpServletRequest req
			) throws Exception{
		//인자값 4개 받음 : db연결,dao,첨부된 file 배열,req(웹경로 출력하기위함)
		//files.length : 첨부하지 않아도 name값은 있기 때문에 1 찍힘 => 이걸로 핸들링 불가		
		
		String ori_name = ""; //사용자가 업로드한 파일명
		String new_name = ""; //랜덤함수 이용해 새로 만든 파일명		
		String url = req.getServletContext().getRealPath("/upload/"); //웹경로

		this.con = dbinfo.getConnection();
		String sql = "";
		
		if( files[0].getSize() > 0 ) { //첨부파일이 있을 경우			
			//여러개의 파일명을 하나의 column에 저장하기 위한 배열
			ArrayList<String> al = new ArrayList<String>(); //원본파일명 담을 배열
			ArrayList<String> al2 = new ArrayList<String>(); //사본파일명 담을 배열

			int w=0;
			while(w<files.length) {
				/*원본*/
				al.add(files[w].getOriginalFilename()); //원본 파일명 담음
				
				/*사본*/
				int com = files[w].getOriginalFilename().indexOf(".");
				String wd = files[w].getOriginalFilename().substring(com); //파일속성명만
				
				String refilenm = this.rename() + wd;
				al2.add(refilenm); //사본 파일명 담음
				
				//사본파일명으로 실제 웹경로에 저장
				FileCopyUtils.copy(files[w].getBytes(), new File(url+refilenm));
				
				w++;
			}
			
			ori_name = String.join(",", al); // 배열을 []떼고 String으로 반환
			new_name = String.join(",", al2);
			
			sql = "insert into gallery (gidx,gwriter,gsubject,gtext,gorifile,gfile,gindate)"
					+ " values ('0',?,?,?,?,?,now())";
			
		}else { //첨부파일이 없을 경우
			//필요한 column만 골라서 저장 - file은 필수값이 아님
			sql = "insert into gallery (gidx,gwriter,gsubject,gtext,gindate)"
					+ " values ('0',?,?,?,now())";
		}
		
		try {
			this.ps = this.con.prepareStatement(sql);
			
			this.ps.setString(1, dao.getGwriter());
			this.ps.setString(2, dao.getGsubject());
			this.ps.setString(3, dao.getGtext());	
			if(ori_name != "") { //첨부파일 있을 경우
				this.ps.setString(4, ori_name);
				this.ps.setString(5, new_name);
			}
			
			this.ps.executeUpdate();
			this.result = "Y";
			
		}catch(Exception e){ //sql 문법 오류 발생시
			this.result = "N";
			System.out.println("db 오류");
		}finally {
			this.ps.close();
			this.con.close();
		}
		
		return this.result;
	}
}

 

String.join("," , 배열) : 클래스 배열을 문자열 형태로 변환해주는 메소드

 

잘들어감