파일업로드시 알아야할것들

1. HTML폼의 전송방식

  기존: application/x-www-form-urlencoded방식    ( get, post ) name = value 기본방법

  파일업로드시 : multipart/form-data <form>태그의 enctype:multipart/form-data + method: post로 설정 필수!!

                          파일 업로드를 위해, 같이 전송되어야함

                          name=value(text) + boundary data ex) form + 첨부파일 요청메세지를 한꺼번에 다읽을수 있다.

 

    어떻게??

 

(Http 요청메세지를 모델링 한게 >>HttpServletRequest다.)

HttpServletRequest에서 InputStream 데이터를 뽑을수있다.

 

2. 스프링에서 제공하는 MultipartFile을 이용

  1) 기존 보드 DTO변경 : 파일저장을 위한 컬럼추가.

     ㄴ List<MultipartFile> dealFiles;

       (클라이언트가 전송하는 바이너리파일 데이터를, 스프링내부mvc에서 MultipartFile객체로만들어서 저장

public class DealBoard_DTO {
		private int deal_number; // 거래번호 
		private String member_id;  //유저아이디
		private String dealType;    // 중고거래구분
		private String product_category;  //상품카테고리(디지털기기,의류 등등) 
		private String product_state; // 상품상태(판매중,거래진행중, 완료 )
		private String board_title; // 제목  
		private int product_price; // 상품가격  
		private String board_content; // 내용 
		private int hits; // 조회수
		private Date write_date; //작성일 
		private List<MultipartFile> dealFiles; // 파일첨부(사진)을 위해 추가함

 

 

         DealFile_DTO 생성  

public class DealFile_DTO {
	private int deal_number;
	private String originalFilename;
	private String storeFilename;

 

 

2) 컨트롤러 수정 (서버에 배포되는 context에 저장 되도록 처리)

	@RequestMapping("deal_Write.do")
	public String dealWrite(DealBoard_DTO dto, HttpSession session) throws IllegalStateException, IOException {
		System.out.println("등록) dto__체크 : " + dto);
		
		// ① List<MultipartFile>정보를 추출하기
		List<MultipartFile> files = dto.getDealFiles(); 
		//System.out.println("List<MultipartFile> files___체크 : "+  files);
		
		// ② 업로드될 서버의 경로 ( 경로 추출을 위해 HttpSession필요)
		String path = WebUtils.getRealPath(session.getServletContext(), "/WEB-INF/dealUpload");
		//spring이 제공하는 WebUtils 클래스. getRealPath메서드( ServletContext, Path )
		//ServletContext객체란? 프로젝트의 context정보(path 등)를 가지고 있는 객체. Path(지정)
		System.out.println("path __________체크 : " + path);
		
		// ③ FileUpload_Service 클래스를 호출해서 실제 서버에 등록되도록 작업
		List<DealFile_DTO> filedtolist =  fileUploadService.uploadFiles(files, path);
		
		// ④ 게시글 등록에 대한 글 + 첨부되파일의 정보를 DB에 저장
		service.insertFile(dto,filedtolist);
		return "redirect:/deal_listAll2.do?dealType=all";  //리스트페이지로
	}

 

 

  ① DTO 에서 MultipartFile 객체들을 추출

  ② 업로드될 서버의 경로 추출

                                                ( 경로 추출을 위해 HttpSession필요, context정보를 담고 있는 ServletContext객체 추출)

          spring이 제공하는 WebUtils 클래스. getRealPath메서드( ServletContext, Path )

          getRealPath메서드 =  프로젝트의 context정보+내가 지정한 경로(Path)  

       (결합하여 getRealPath를구함)
               ※ ServletContext객체란?  서버에배포되는 실제경로 + context정보를 가지고 있는 객체
     

3) 파일업로드 기능을 수행하는 서비스를 작성 ( 실제 서버에 저장되도록)

****** FileUpload_Service.java  생성   ( 파일을 업로드한 후 이 정보를 DealFile_DTO로 변환해서 리턴 )

@Service
public class FileUpload_Service {
	//파일을 업로드한 후 이 정보를 DealFile_DTO로 변환해서 리턴
	//private int deal_number;
	public List<DealFile_DTO> uploadFiles(List<MultipartFile> multipartFiles, String path) throws IllegalStateException, IOException{
		List<DealFile_DTO> filedtolist = new ArrayList<DealFile_DTO>() ;
		
		//multipartFiles로 받은 것 하나씩 꺼내기
		for(MultipartFile multipartFile : multipartFiles) {
			if(!multipartFile.isEmpty()) {
				// 클라이언트가 업로드한 원래파일명
				String originalFilename = multipartFile.getOriginalFilename();
				System.out.println("originalFilename___체크 : " + originalFilename); //확인완료
						
				// 서버에서 식별할수 있도록 파일명을 변경 (uuid)
				String storeFilename = createStoreFileNmae(originalFilename);
				             
			    //서버(현재내pc)경로 + \(File.separator) + 파일명  
				//File객체를 실제경로에 저장 ( .transferTo(new File()사용)
				// transferTo(new File( ~~ )) : boundary 데이터를 파일로만들어줘~!
				multipartFile.transferTo(new File(path+File.separator+storeFilename));  //중복되지않도록 uuid로 만든 storeFilename으로 생성
				
				filedtolist.add(new DealFile_DTO(originalFilename, storeFilename)); //dto생성자 2개짜리 만들어야함
			}
		}
		return filedtolist;
	}
	
	// 클라이언트가 입력한 파일명을 중복되지 않고 식별할수 있도록 UUID사용 ( UUID란? 32자리 16진수로 표기 )
	private String createStoreFileNmae(String originalFilename) {
		//확장자명을 만들어주기위해추가
		int position = originalFilename.lastIndexOf(".");  // 확장자 . 위치   ex) dabc.jpeg
		String ext = originalFilename.substring(position+1);
		
		String uuid = UUID.randomUUID().toString();
		return uuid+"."+ext;
	}

  ③ FileUpload_Service로 전달해서 실제파일이 전송되도록 처리

  ④ BoardService로 보내서 디비에 저장되도록 처리

 

 

 

4) 서비스 수정 (serviceImpl.java)

	//업로드한파일을 목록조회
	@Override
	public List<DealFile_DTO> getFileList(int deal_number) {
		System.out.println("서비스임플 deal_number 파라미터 체크 : " + deal_number);
		return dao.getFileList(deal_number);
	}
	//중고거래글 등록 ( +첨부파일) DealBoard_DTO테이블과 DealFile_DTO테이블에 저장
	@Override
	public int insertFile(DealBoard_DTO dto, List<DealFile_DTO> listfiledto) {
		dao.writeProd(dto);
		dao.insertFile(listfiledto);
		return 0;
	}

트랜잭션처리 하지않은상태

 

 

5) DAO 수정 (DAOImpl.java)

//중고거래글 등록 ( +첨부파일) DealBoard_DTO테이블과 DealFile_DTO테이블에 저장
	@Override
	public int insertFile(List<DealFile_DTO> filedtolist) {
		return sqlSession.insert("com.multi.ongo.deal.insertFile", filedtolist);
	}


	//업로드한파일을 목록조회
	@Override
	public List<DealFile_DTO> getFileList(int deal_number) {
		return sqlSession.selectList("com.multi.ongo.deal.getFileList", deal_number);
	}

 

현재는 첨부파일 링크 클릭시, 링크로만 확인가능

 

 

 

등록jsp

<div class="grid-item colspan2">
        <label for="HOFS_DTADR">사진</label>
    <div class="tbl-basic-td">
        <div class="input-wrap w100">
                <input type="file" name="dealFiles" onchange="document.getElementById('dealFiles').src = window.URL.createObjectURL(this.files[0])" accept="dealUpload/*" multiple="multiple">
                <img src="/ongo/images/myphoto.jpg" id="dealFiles" style="width: 100px">
        </div>
    </div>
</div>

 

읽기 컨트롤

@RequestMapping("dealRead.do")
	public ModelAndView dealRead(int deal_number, String state) {
		
		//첨부파일목록 불러오기 위하여작성
		List<DealFile_DTO> filedtolist = service.getFileList(deal_number);
		 
		DealBoard_DTO dealRead = service.dealRead(deal_number);
		String view = "";
		if(state.equals("READ")) {	
			//System.out.println("조회수 처리전 : "+dealRead.getHits()+ "/______/매개변수확인" + deal_number);
			service.hits_update(deal_number);//조회
			//System.out.println("조회수 처리후 : "+dealRead.getHits()  + "/______/매개변수확인" + deal_number);
			view ="dealBoardRead";
		}else {
			System.out.println("컨트롤 업데이트 진입 : " + deal_number); //넘어감
			view ="dealBoardUpdate";
		}
		ModelAndView mav = new ModelAndView(view);
		mav.addObject("dealRead",dealRead);
		mav.addObject("filedtolist",filedtolist); //파일첨부 결과 공유
		//System.out.println("컨트롤 공유 dealread 체크:" + dealRead);
		//System.out.println("찍먹state:" + state);
		return mav;
	}

 

읽기jsp

<div class="grid-item colspan2">
    <label for="HOFS_DTADR">첨부파일</label>
    <div class="tbl-basic-td">
        <div class="input-wrap w100">
            <c:forEach var="file" items="${filedtolist}" >
                <label for="HOFS_DTADR"><a href="/ongo/dealUpload/${file.storeFilename }">${file.originalFilename}</a></label><br/>
            </c:forEach>


        </div>
    </div>
</div>

 

 

 

'스프링MVC' 카테고리의 다른 글

json  (0) 2023.01.18
ajax  (0) 2023.01.18
스프링-파일업로드(2) (mybatis사용)  (0) 2023.01.18
@PathVariable 사용  (0) 2023.01.18
스프링-파일업로드(1) 작업흐름 (mybatis사용)  (0) 2023.01.16

+ Recent posts