1. 파일 다운로드

2. 댓글기능

 

3. 에이작스리스트 무한휠에서 네비바 형식으로 변경 (부트스트랩 버튼 그룹)

4. 보드테이블에 아이피주소 넣기

5. 비회원 댓글은 아이피번호 노출되도록?

6. '수정하기'는 '작성하기' 개선 후에 다시 만들기


fileDTO 대신 멀티파트파일로 받기

file.transferTo

 

FileService 생성

 

 

 

 

 

 

# 부분에 다운로드 기능

 

 


클릭시 동작하는

파일컨트롤러 만들기

	// 클릭시 파일 다운로드
	@RequestMapping("downLoadFile")
	public void downLoadFile(int seq, HttpServletResponse resp) throws Exception {
		FileDTO fdto = bservice.getFileBySeq(seq);
		String filePath = session.getServletContext().getRealPath("upload/"+fdto.getUploader_id());
		System.out.println("filePath : "+filePath);
		File target = new File(filePath+"/"+fdto.getStored_file_name());
		try(DataInputStream dis = new DataInputStream(new FileInputStream(target));
		ServletOutputStream sos = resp.getOutputStream();){
				
		String fileName = new String(fdto.getOriginal_file_name().getBytes("utf8"),"iso-8859-1");	
			
		resp.reset();
		resp.setContentType("application/octet-stream");
		resp.setHeader("Content-disposition", "attachment;filename="+fileName+";");
		
		byte[] fileContents = new byte[(int)target.length()];
		dis.readFully(fileContents);
		
		sos.write(fileContents);
		sos.flush();
		}
	}

링크를 클릭하면

일단은 받을 값을 보여주도록하기

일단은 리다이렉트 /

 

 

하드디스크 파일에 '빨대' 연결

첨부파일 보내기

	// 클릭시 파일 다운로드
	@RequestMapping("downLoadFile")
	public void downLoadFile(int seq, HttpServletResponse resp) throws Exception {
		FileDTO fdto = bservice.getFileBySeq(seq);
		String filePath = session.getServletContext().getRealPath("upload/"+fdto.getUploader_id());
		System.out.println("filePath : "+filePath);
		File target = new File(filePath+"/"+fdto.getStored_file_name());
		try(DataInputStream dis = new DataInputStream(new FileInputStream(target));
		ServletOutputStream sos = resp.getOutputStream();){
				
		String fileName = new String(fdto.getOriginal_file_name().getBytes("utf8"),"iso-8859-1");	
			
		resp.reset();
		resp.setContentType("application/octet-stream");
		resp.setHeader("Content-disposition", "attachment;filename="+fileName+";");
		
		byte[] fileContents = new byte[(int)target.length()];
		dis.readFully(fileContents);
		
		sos.write(fileContents);
		sos.flush();
		}
	}

 

BoardProject(0608 강사님 코드).zip
0.19MB


파일 이름이 한글

 

크롬 인코딩 방식으로 인코딩 해서 보내주기

'디지털 컨버전스 > Spring' 카테고리의 다른 글

[Spring Framework] 정리  (0) 2020.06.08
[Spring Framework] 댓글  (0) 2020.06.08
[Spring Framwork] 파일 업로드 개수  (0) 2020.06.05
[Spring Framework] 파일업로드  (0) 2020.06.05
[Spring Framework] 트랜젝션 처리  (0) 2020.06.05

 

 

 

 

 


강사님 파일

 

BoardProject.zip
0.18MB


 

1. JSTL 오류 해결

2. 에이작스리스트 무한휠에서 네비바 형식으로 변경

3. 보드테이블에 아이피주소 넣기

4. 비회원 댓글은 아이피번호 노출되도록?

5. 댓글 기능

6. '수정하기'는 썸머노트&파일수정 포함해서 다시 만들기

 

BoardProject.zip
0.11MB

파일컨트롤러 생성


Apache Commons FileUpload & Apache Commons IO

라이브러리 설치

 

스프링에서는

cos.jar를 쓸수도 있지만

아파치 커먼 파일업로드 라이브러리가 더 권장

 

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

 

pom.xml

 

Apache Commons FileUpload는 커먼스 IO에 의존성을 갖고 있다.

(그냥 실행하면 class not found 나온다!)

 

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

 


servlet-context.xml

 

 

 

	<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<beans:property name="maxUploadSize" value="10485760"/>
	</beans:bean>

 

 

 

 

 

 

 


저장 경로 설정

 

파일이름 중복 줄이기 (밀리세컨드값 붙여서)

		String systemFileName = System.currentTimeMillis()+"_"+file.getOriginalFilename();

 

 

경로가 존재하지 않는다면 만들어 주기

		if(!tempFilePath.exists()) {tempFilePath.mkdir();}
package kh.spring.controller;

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileController {
	@Autowired
	private HttpSession session;
	
	@RequestMapping("fileUpload")
	public String fileUpload(String writer, String contents, MultipartFile file) throws Exception{
		
		String filePath = session.getServletContext().getRealPath("upload");
		File tempFilePath = new File(filePath);
		if(!tempFilePath.exists()) {tempFilePath.mkdir();}
		String systemFileName = System.currentTimeMillis()+"_"+file.getOriginalFilename();
		File targetLoc = new File(filePath+"/"+systemFileName);
		file.transferTo(targetLoc);
		return "home";
	}
	
}

 


업로드 경로

 


Q. 회원별 폴더 만들기

아이디로 폴더를 만들고 경로에 넣기


Q. 특정 파일만 올리려고 하는 경우?

 


 

매개변수 3개나 받는 것보다는 DTO로 받는게 좋다

	public String fileUpload(String writer, String contents, MultipartFile file) 

멀티파트 자체가 클래스 의존적임

 


파일 여러개를 업로드 하는 경우

 

	@RequestMapping("filesUpload")
	public String filesUpload(MultipartFile[] files) throws Exception{
		String filePath = session.getServletContext().getRealPath("upload");
		
		for(MultipartFile file : files) {
			System.out.println(file.getOriginalFilename());
			//file.transferTo(new File());
			String systemFileName = System.currentTimeMillis()+"_"+file.getOriginalFilename();
			File targetLoc = new File(filePath+"/"+systemFileName);
			file.transferTo(targetLoc);
		}
		return "home";
	}


빈 파일 생성 차단

	@RequestMapping("filesUpload")
	public String filesUpload(MultipartFile[] files) throws Exception{
		String filePath = session.getServletContext().getRealPath("upload");

		for(MultipartFile file : files) {
			if(!file.isEmpty()) {
				System.out.println(file.getOriginalFilename());
				String systemFileName = System.currentTimeMillis()+"_"+file.getOriginalFilename();
				File targetLoc = new File(filePath+"/"+systemFileName);
				file.transferTo(targetLoc);
			}
		}
		return "home";
	}

 

※ 폼의 name과 매개변수의 이름 같아야 연결된다 (file / files 확인)

 


❔ 파일 네임이 같으면 덮어쓰기?

 

드문 경우지만 그럴때 파일이름 변경해서 중복 피하기

 

UUID를 어떻게 믿지?

UUID : 랜덤한 32글자를 붙인다.


매개변수로 DTO 두개 이상 가능

필드 이름에 맞추어서 DTO 구분해 들어간다.


1. 글쓰기에 파일 업로드도 적용 해보기 (다중 파일?)

 

보드 서비스, 파일 서비스 두개?

보드DAO 파일DAO

 

BoardProject.zip
0.11MB

https://offbyone.tistory.com/69

 

스프링프레임웍 ajax 파일업로드 - jQuery, FormData, jQuery Form Plugin 사용

이 글에서는 스프링 프레임웍 환경에서 ajax를 통한 파일 업로드 방법을 알아 보겠습니다. 서버와의 ajax 통신에는 jQuery를 사용하고 업로드를 위해서 FormData 객체를 사용하는 방법과 jQuery Form Plugin

offbyone.tistory.com

 

2. 에이작스리스트 무한휠에서 네비바 형식으로 변경

3. 보드테이블에 아이피주소 넣기

4. 비회원 댓글은 아이피번호 노출되도록?

5. 댓글 기능

6. '수정하기'는 '작성하기' 개선 후에 다시 만들기

 

https://jyh1536.tistory.com/63

 

Spring 개발 - 게시판 만들기(15) - 파일 다중 업로드 및 게시판 수정하기(파일 업로드)

본 내용은 혼자 공부하기 위하여 다른 포스트를 보면서 저에게 필요한 부분과 궁금했던 부분을 추가하여 게시하는 곳입니다. 궁금한 것에 대한 것은 모르는 것이 많겠지만 함께 알아보도록 노�

jyh1536.tistory.com

https://addio3305.tistory.com/83?category=772645

 

스프링(Spring) 개발 - (13) 파일 업로드 & 다운로드 (1/3)

이번글에서는 첨부파일 업&다운로드에 대해서 이야기 하려고 합니다. 웹에서 첨부파일은 상당히 문제가 많이 일어나는 부분이기도 합니다. 실제로 프로젝트중에서 첨부파일때문에 오픈이 지연

addio3305.tistory.com

 

원자성을 띈다 : 두 기능이 동시에 성공해야만 함

 

작업의 원자성이 필요한 경우

 

 

트랜젝션을 관리하면서 코드를 짤 수 있다

 

ex 구매목록 배송목로

 

 

커밋을 직접하면 트랜젝션을 제어할 수 있음

둘중 하나라도 예외가 생기면 rollback

 

jdbc 탬플릿을 쓰면 우리가 커밋을 통제 할 수 없음


 

 

어노테이션 방식으로 구현하기

 

자바스크립트 데이터 테이블즈 API : 네비게이팅 알고리즘을 자바스크립트가 만들어줌

 

-> 네트워크로 무조건 모든 리스트를 받아야함 : 비효율

 



 

 

 

네비게이터 만드는 기능 -> dao가 아닌 서비스 쪽에

파이널 상수값은 전부다 대문자로

 

 

네비게이터 조립 작업은 서비스가, 

 


 

 

 

 

 

 

서비스 레이어의 등장 배경

 

기존의 방식도 나쁘진 않지만 좀 더 미래 지향적인 코드를 적용하기

장기적으로 유리

 

 

현재 우리가 짜는 컨트롤러 코드는 플랫폼 종속성을 갖는다.

 

톰캣, 스프링 프레임 워크 : 현재 의존하고 있는 플랫폼

 

 

DAO는 데이터베이스 플랫폼에 종속

 

 

모호성이 생기는 시점 : 이 코드가 컨트롤러인가? DAO인가?

 

게시판의 네비게이터 로직

이전에는 DAO에 넣었지만 원래 DAO는 데이터베이스 관련된 기능만 들어가야 최적화

컨트롤러는 웹과 관련된 기능만 담당해야 최적화.

 

 


서비스레이어

플랫폼 종속성을 가지지 않는 분리 가능한 매커니즘을 저장하는 계층

비지니스 로직 저장

 

리퀘스트, 리스폰스, session 등 웹 관련은 컨트롤러에만 존재

connection은 DAO에만 존재

컨트롤러와 DAO가 받아온 숫자만 서비스레이어로 전달

서비스레이어는 덧셈뺄셈 로직만 구동

 

 

장점 : 서비스레이어는 웹이 아닌 네이티브로 가져와도 재활용 가능

똑같은 자바 프로젝트라면 복붙했을때 다 동작

 


 

 getSha512 를 매서드로 만들어서 서비스계층이 갖도록

서비스 패키지 추가

컨트롤러가 서비스레이어를 사용하고 서비스레이어가 DAO를 사용

 

컴포넌트의 자손 중

@Service

컨트롤러에서 서비스로 boardWrite() 콜

form 으로 받는값 뿐아니라 session에서 꺼내는 경우 (글쓴이 아이디)

 

아이피가 필요한 경우

리퀘스트는 오토와이어드도 해서는 안되고 서비스에서 쓰이지 않음 -> 컨트롤러에서만 사용

 

 

 

의존성 없는 코드를 구분하기 어려운 상황도 있음.

서비스레이어를 거쳐서 사용하기 불편하지만 그래도 미래를 대비해서 사용할 것

 

mvc2에서는 웹콘텐츠 안에 이미지폴더

 

Spring에서는?

 

WEB-INF : 외부접속 차단

이미지태그 : 

 


가짜 이름으로 이미지 태그 사용

개발자도구 - 네트워크

새로고침(F5)을 하면 url을 다시 요청

새로고침 할 때마다 한개의 리퀘스트, 한개의 리스폰스 주고 받을 것이라 추정

하지만 실제로는

리퀘스트 3개

 

네이버 리퀘스트는 더 많다

 

 

클라이언트가 리퀘스트를 쏘면 서버는 디스패처 서블릿에 넘긴다.

디스패터 서블렛이 컨트롤러에 물어봄

 

 

이미지태그라는 텍스트를 받아옴

이미지 자체는 서버에만 존재

 

이미지를 요구하는 2번째 리퀘스트 발생

 

 

1. 컨트롤러/라는 페이지 요청

2. 제이쿼리 cdn 요청 (제이쿼리 사이트에 요청)

3. 이미지 요청

 

 

사용자가 원하지 않는 리퀘스트를 보내도록 함

CSRF : 싸이월드 방문자 추적기, 해킹...


이미지를 어디에 넣어야 하고 어떻게 동작하는가?

 

 url을 요청받았을 때 처리 과정

'abc.jpg' 라는 url을 요청받았을 때

경로없이 이름만 쓰면 상대경로로 같은 위치에서 찾는다

'abc.jpg' 는 컨트롤러에 갈 url이 아님

 

리퀘스트맵핑 정보가 없다.

 

servlet-context.xml

 

<annotation-driven/>

 

 

<annotation-driven/> 이 동작하는 바람에 이미지를 리퀘스트 맵핑에서 찾게 됨

그렇다고 지우면 이미지는 찾아지나 리퀘스트앱핑이 동작하지 않음

 

<resources/>

맵핑에 url이 "/resources/**" 로 되어있는 것들은 컨트롤러가 아닌 "/resources/"에서 찾도록

 

클라이언트의 요구 : 외부접근

resources 폴더가 WEB-INF 밖에 존재하는 이유!

 

 

이미지 요청이 컨트롤러로 들어간 상황

 

앞에 /resources/를 넣어주면

못찾아도 컨트롤러 오류 메세지는 나오지 않음

 

제대로 된 경로 ( /resources/img/late.jpg )를 넣어주면

 


로케이션은 실제 존재해야 하지만

mapping 정보는 변경 가능

 

헷갈릴 수는 있지만 편할 수도

+ Recent posts