Spring MVC HTTPで送られてきた画像ファイルを特定のディレクトリに保存する


スポンサーリンク

ApacheからHTTP POSTで送られた画像ファイルを、Spring MVC側で受け取って、特定のディレクトリに格納するサンプルを作りました。

ディレクトリ構成はこんな感じです。

f:id:sho322:20140721190932j:plain

目次

mvc-config.xml

ポイントは、context:component-scanの記述の部分で、AutowiredでServiceをインジェクションするための設定を書いています。

multipartResolverの部分はファイルをアップロードするときに使うクラスで、これをbeanで定義する必要があります。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Uncomment and your base-package here: -->
         <context:component-scan
            base-package="shiori.controller"/> 
    <context:component-scan base-package="shiori.service" />
    <context:component-scan base-package="shiori.dao" />
    

    <mvc:annotation-driven />

	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	        <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' -->
	        <property name="prefix" value="/WEB-INF/view/"/>
	        <property name="suffix" value=".jsp"/>
	</bean>
	
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="2000000"/>
	</bean>

	<bean id="imageDao" class="shiori.dao.ImageDaoImpl">
	    <property name="imageSaveDir" value="C:\xampp\htdocs\sample\image" />
	    <property name="imageAbsoluteSaveDir" value="\sample\image\"/>
	</bean>
</beans>

ImageController

コントローラの部分では、画像ファイルを受け取って、それをDAOに渡しています。

package shiori.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

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

import shiori.dao.ImageDao;
import shiori.domain.Image;
import shiori.service.ImageService;

@Controller
public class ImageController {
	
	private String imageDir;
	
	public String getImageDir() {
		return imageDir;
	}

	public void setImageDir(String imageDir) {
		this.imageDir = imageDir;
	}

	@Autowired
	ServletContext context;
	
	@Autowired
	private ImageService imageService;
	
	@RequestMapping(value = "img_save", method=RequestMethod.POST)
	public @ResponseBody Image saveProduct(HttpServletRequest request,
					@RequestParam("file") MultipartFile file) throws IllegalStateException, IOException {

		ImageDao dao = imageService.getImageDao();
		Image image = dao.save(file);		
		return image;
	}
	
	@RequestMapping(value = "img_list")
	public @ResponseBody List getImageList(HttpServletRequest request)
				throws IOException {
		ImageDao dao = imageService.getImageDao();
		List urls = dao.getAllImageUrls();
		
		
		return urls;
		
	}
}

ImageDaoImpl.java

DAOでは特定のディレクトリに、送られてきた画像を保存する処理が書かれています。

package shiori.dao;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import shiori.domain.Image;

@Service
public class ImageDaoImpl implements ImageDao {
	//フルパスでファイルの格納先を定義する
	private String imageSaveDir;
	
	//htdocsの下のパスを設定する
	private String imageAbsoluteSaveDir;
	
	private List<String> imageUrls;
	
	public List<String> getImageUrls() {
		List<String> urls = new ArrayList<String>();
		
		File dir = new File(imageSaveDir);
		File[] files = dir.listFiles();
		
		for (File file : files) {
			String fileName = file.getName();
			String url = "http://localhost/" +imageAbsoluteSaveDir + fileName;
			urls.add(url);
		}
		return urls;
	}

	public void setImageUrls(List<String> imageUrls) {
		this.imageUrls = imageUrls;
	}

	public String getImageAbsoluteSaveDir() {
		return imageAbsoluteSaveDir;
	}

	public void setImageAbsoluteSaveDir(String imageAbsoluteSaveDir) {
		this.imageAbsoluteSaveDir = imageAbsoluteSaveDir;
	}

	public String getImageSaveDir() {
		return imageSaveDir;
	}

	public void setImageSaveDir(String imageSaveDir) {
		this.imageSaveDir = imageSaveDir;
	}
	
	public Image save(MultipartFile imageFile) {
		Image image = new Image();
		
		Date postDate = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
		String dateStr = sdf.format(postDate);
		
		
		if (imageFile.getSize() > 0) {
			String imageFileName = dateStr + "_" +imageFile.getOriginalFilename();
			
			image.setName(imageFileName);
			image.setSize(imageFile.getSize());
			image.setPostDate(postDate);
			image.setUrl(imageAbsoluteSaveDir + imageFileName);
			
			//本来はこのimageをDBにつっこむけど、今回は実装しない
			
			File file = new File(imageSaveDir, imageFileName);
			if (!file.exists()) {
				File dir = new File(imageSaveDir);
				dir.mkdir();
			}
			try {
				imageFile.transferTo(file);
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return image;
	}

	public List<Image> getAllImages() {
		//別に画像ファイルを送る必要はない
		return null;
	}

	public List<String> getAllImageUrls() {
		
		return getImageUrls();
	}

}

ImageServiceImpl

Daoを持つサービスです。

package shiori.service;

import java.util.List;

import shiori.dao.ImageDao;
import shiori.domain.Image;

public interface ImageService {
	List<Image> getAllImages();
	Image save(Image image);
	ImageDao getImageDao();
}

Image.java

これは画像ファイルのBeanです。

package shiori.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.springframework.web.multipart.MultipartFile;

public class Image implements Serializable {

	private static final long serialVersionUID = 7302826202936253750L;
	
	private long id;
	private String name;
	private long size;
	private String url;
	private Date postDate;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public long getSize() {
		return size;
	}
	public void setSize(long size) {
		this.size = size;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public Date getPostDate() {
		return postDate;
	}
	public void setPostDate(Date postDate) {
		this.postDate = postDate;
	}

}

SpringによるWebアプリケーションスーパーサンプル 第2版

SpringによるWebアプリケーションスーパーサンプル 第2版