gikoha’s blog

個人的メモがわり

Rooでのファイルアップロード/ダウンロード

まあ単純なspring MVCなわけだけれど..

AbookController.java

package abook.web;

import info.ineighborhood.cardme.engine.VCardEngine;
import info.ineighborhood.cardme.io.VCardWriter;
import info.ineighborhood.cardme.vcard.VCard;
import info.ineighborhood.cardme.vcard.VCardImpl;
import info.ineighborhood.cardme.vcard.VCardVersion;
import info.ineighborhood.cardme.vcard.types.AddressType;
import info.ineighborhood.cardme.vcard.types.BeginType;
import info.ineighborhood.cardme.vcard.types.EndType;
import info.ineighborhood.cardme.vcard.types.FormattedNameType;
import info.ineighborhood.cardme.vcard.types.NameType;
import info.ineighborhood.cardme.vcard.types.TelephoneType;
import info.ineighborhood.cardme.vcard.types.VersionType;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.roo.addon.web.mvc.controller.RooWebScaffold;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
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.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;

import abook.main.Abook;

@RooWebScaffold(path = "abooks", formBackingObject = Abook.class)
@RequestMapping("/abooks")
@Controller
public class AbookController
{
	static String getVCardString(Long id)
	{
		Abook person = Abook.findAbook(id);
		VCard vcard = new VCardImpl();

		vcard.setBegin(new BeginType());
		vcard.setVersion(new VersionType(VCardVersion.V3_0));
		vcard.setName(new NameType(person.getName()));
		vcard.setFormattedName(new FormattedNameType(person.getName()));
		AddressType addr = new AddressType();
		addr.setStreetAddress(person.getAddress());
		addr.setPostalCode(person.getPostalnum());
		vcard.addAddress(addr);
		vcard.addTelephoneNumber(new TelephoneType(person.getPhone()));
		vcard.setEnd(new EndType());

		VCardWriter writer = new VCardWriter();
		writer.setVCard(vcard);
		String vstring = writer.buildVCardString();
		return vstring;
	}

	@RequestMapping(value = "upload", method = RequestMethod.GET)
	public String showUploadJSP(Model model)
	{
		return "abooks/upload";
	}

	@RequestMapping(value = "uplink", method = RequestMethod.POST)
	public String handleFormUpload(@RequestParam("file") MultipartFile file,
			HttpServletRequest request) throws IOException
	{
		VCardEngine vcardParser = new VCardEngine();
		String vcfstr = new String(file.getBytes());

		VCard vcard = vcardParser.parse(vcfstr);
		String name = vcard.getFormattedName().getFormattedName();
		if (!name.isEmpty())
		{
			String phone = vcard.getTelephoneNumbers().next().getTelephone();
			String addr = vcard.getAddresses().next().getStreetAddress();
			String post = vcard.getAddresses().next().getPostalCode();
			// System.out.println("Name:"+name+" Addr:〒 "+post+" "+addr+" Phone:"+phone);
			Abook person = new Abook();
			person.setName(name);
			person.setAddress(addr);
			person.setPhone(phone);
			person.setPostalnum(post);
			person.persist();
			return "redirect:/abooks/"
					+ UriUtils.encodePathSegment(person.getId().toString(), request.getCharacterEncoding());
		}

		return "abooks";
	}

	@RequestMapping(value = "vCard/{id}", method = RequestMethod.GET)
	public void vCard2(HttpServletRequest request,
			HttpServletResponse response, @PathVariable("id") Long id)
			throws IOException
	{
		Abook person = Abook.findAbook(id);
		String vstr = getVCardString(id);
		response.reset();
		if (request.getHeader("User-Agent").indexOf("MSIE5.0") > -1)
		{
			response.setHeader("content-Type", "dodemo/iirasi;");
		}
		else
		{
			response.setHeader("content-Type", "application/unknown");
		}
		response.setHeader("Content-Disposition",
				"attachment;filename=\"test.vcf\"");
		OutputStream out = response.getOutputStream();
		IOUtils.copy(new ByteArrayInputStream(vstr.getBytes()), out);
		out.flush();
	}

}

src/main/resources/applicationContext.xml に MultipartResolver bean を追加する必要がある

   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

かっこ良くするために IOUtilsを使ったのでインポートしておく perform eclipseを忘れないでね
pom.xmlに追加

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.0.1</version>
</dependency>

upload画面の作成
WEB-INF/views/abooks/upload.jspx

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields"
	xmlns:jsp="http://java.sun.com/JSP/Page"
	xmlns:form="http://www.springframework.org/tags/form"
	xmlns:spring="http://www.springframework.org/tags" version="2.0">
	<jsp:directive.page contentType="text/html;charset=UTF-8" />
	<jsp:output omit-xml-declaration="yes" />

	<form:form action="uplink" method="post" enctype="multipart/form-data">
		<input name="file" type="file" id="file" />
		<br />
		<input type="submit" value="送信する" />
		<input type="reset" value="リセット" />
	</form:form>
</div>

画面を追加したから、View名で参照できるように WEB-INF/views/abooks/views.xml に追加

	<definition extends="default" name="abooks/upload">
		<put-attribute name="body" value="/WEB-INF/views/abooks/upload.jspx"></put-attribute></definition>

メニューにuploadリンクを追加しておく
WEB-INF/views/menu.jspx に追加 の下に

        <menu:item id="upload_abook" url="/abooks/upload" label="Upload" />

アドレスブックからDrag & Drop した vcf ファイルを Upload を押して読ませると、
データベースに登録される(東京都が抜けた!?)

FireFoxのWebコンソールは便利だね