File Upload

Code

package com.u2ware.springfield.sample.others.upload;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Transient;

import lombok.Getter;
import lombok.Setter;

import org.springframework.web.multipart.MultipartFile;

import com.u2ware.springfield.config.Springfield;
import com.u2ware.springfield.config.Springfield.Strategy;
import com.u2ware.springfield.support.multipart.DownloadFile;

@Springfield(
	strategy=Strategy.JPA,
	methodLevelMapping={"*","read.stream","read.download"}
)
@Entity
public class AttachedFile implements DownloadFile{
	
	@Transient 
	private @Getter @Setter MultipartFile multipartFile;
	
	@Id @GeneratedValue
	private @Getter @Setter Integer id;
	private @Getter @Setter String contentFile;
	private @Getter @Setter String contentName;
	private @Getter @Setter String contentType;
	private @Getter @Setter long contentSize;
}
		
package com.u2ware.springfield.sample.others.upload;

import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.u2ware.springfield.repository.EntityRepository;
import com.u2ware.springfield.service.EntityServiceImpl;
import com.u2ware.springfield.support.multipart.MultipartFileHandler;
import com.u2ware.springfield.validation.RejectableException;

@Service
public class AttachedFileService extends EntityServiceImpl<AttachedFile, Integer>{

	@Autowired 
	private MultipartFileHandler multipartFileHandler;

	@Autowired @Qualifier("attachedFileRepository") 
	private EntityRepository<AttachedFile, Integer> attachedFileRepository;
	
	@Override
	protected EntityRepository<AttachedFile, Integer> getRepository() {
		return attachedFileRepository;
	}

	@Override
	@Transactional
	public AttachedFile create(AttachedFile entity) {
		try {
			MultipartFile multipartFile = entity.getMultipartFile(); 
			String contentFile = multipartFileHandler.saveFile(multipartFile);
			
			entity.setContentFile(contentFile);
			entity.setContentName(multipartFile.getOriginalFilename());
			entity.setContentType(multipartFile.getContentType());
			entity.setContentSize(multipartFile.getSize());
		} catch (IOException e) {
			throw new RejectableException("multipartFile" , "id");
		}
		AttachedFile newEntity = getRepository().create(entity);
		logger.debug(newEntity.getId());
		
		return newEntity;
	}
	
	@Override
	@Transactional
	public AttachedFile delete(AttachedFile entity) {
		AttachedFile newEntity = getRepository().read(entity);
		try {
			multipartFileHandler.deleteFile(newEntity.getContentFile());
		} catch (IOException e) {
			throw new RejectableException("multipartFile" , "id");
		}
		getRepository().delete(newEntity);
		return entity;
	}
}
		

Beans

@Springfield(strategy=Strategy.JPA) 선언으로 다음 4개의 Bean 이 등록 된다. 자동생성 하려는 Bean(Name)이 이미 존재한다면, @Springfield 는 Bean 을 따로 생성하지 않는다.

bean name bean type bean implement
"attachedFileController"EntityController<AttachedFile, AttachedFile>com.u2ware.springfield.controller. EntityHandler
"attachedFileValidator" EntityValidator<AttachedFile, AttachedFile> com.u2ware.springfield.validation. EntityValidatorImpl
"attachedFileService" EntityService<AttachedFile, AttachedFile> com.u2ware.springfield.sample.others.upload. AttachedFileService
"attachedFileRepository"EntityRepository<AttachedFile, Integer>com.u2ware.springfield.repository.jpa. EntityJpaRepository

RequestMapping

매핑 경로 HTTP Method Controller Method 이름 예제 Command 객체 예제 매핑 경로
/{topLevelMapping}/ GET home() AttachedFile/others/upload/
/{topLevelMapping} GET findForm() AttachedFile/others/upload
/{topLevelMapping} POST find() AttachedFile/others/upload
/{topLevelMapping}/{id} GET read() JpaBean/others/upload/1
/others/upload/1.stream
/others/upload/1.download
/{topLevelMapping}/new GET createForm()AttachedFile/others/upload/new
/{topLevelMapping}/new POST create() AttachedFile/others/upload/new
/{topLevelMapping}/{id}/editGET updateForm()AttachedFile/others/upload/1/eidt
/{topLevelMapping}/{id}/editPUT update() AttachedFile/others/upload/1/eidt
/{topLevelMapping}/{id}/editDELETEdelete() AttachedFile/others/upload/1/eidt

MultipartFileHandler

Note:
Springfield 는 file upload 를 위해 com.u2ware.springfield.support.multipart.MultipartFileHandler 인터페이스와 구현체를 제공한다.
인자로 사용되는 com.u2ware.springfield.support.multipart.UploadFile는 업로드된 파일의 실제 저장 경로 및 이름을 결정짓는다.
public interface MultipartFileHandler {

	public String saveFile(MultipartFile multipartFile) throws IOException;
	public String saveFile(MultipartFile multipartFile, String saveName) throws IOException;
	public String saveFile(MultipartFile multipartFile, UploadFile policy) throws IOException;
	public String saveFile(MultipartFile multipartFile, String saveName , UploadFile policy) throws IOException;

	public File findFile(String contentFile) throws IOException;
	public void deleteFile(String contentFile) throws IOException;
}
		
public interface UploadFile {

	public String getContentFile(MultipartFile multipartFile) ;
	public String getContentFile(MultipartFile multipartFile, String name) ;
}
		
application-context.properties:
파일업로드 사이즈와 저장 위치는 설정이 가능하다.

webmvc.multipart.maxUploadSize=20000000
webmvc.multipart.location=

DownloadFile

Note:
Springfield 가 제공하는 MultipartFileView 는 com.u2ware.springfield.support.multipart.DownloadFile 을 model 로 부터 찾아서 동작한다.
public interface DownloadFile {

	public String getContentFile();
	public String getContentName();
	public String getContentType();
	public long getContentSize();
}