で、spring boot for java が、おおよそ分かってきた気がするので、 webアプリっぽい機能を一つ書いてみた。以下
html
<html lang="ja"> <body> <table> <thead> <tr> <th style="width:120px;">ファイル</th> <td id="file_drop_zone" colspan="2" style="width:500px;"> ここにファイルをドラッグ&ドロップして下さい </td> </tr> </thead> <tbody id="file_dropped_zone"> </tbody> <tfoot> <tr> <td></td> <td colspan="2"> <button type="button" onClick="doc_list.submit_docs()">登録実行</button></td> </tr> </tfoot> </table> <script id="tmpl_droped_file" type="text/x-jquery-tmpl"> <tr> <td><input type="hidden" class="fileContent" name="fileContent"></td> <td class="fileName"></td> <td class="fileSize"></td> </tr> </script> <script src="/jquery/jquery-3.2.1.min.js"></script> <script src="/jquery/jquery.tmpl.js"></script> <script src="/jquery/jquery.json.js"></script> <script src="/js/DocList.js"></script> <script> $(document).ready(function(){ doc_list.init_page(); }); </script> </body> </html>
javascript
ドラッグ&ドロップでファイルを開き、 reader.readAsDataURL(file) によりBASE64 の文字列でサーバ側にPOSTしています。
(function() { var DocList = function() {}; DocList.prototype = { init_page: function(){ this.init_file_drop_zone(); }, init_file_drop_zone: function(){ var this_obj = this; $('#file_drop_zone').on("dragover",function(evt){ evt.stopPropagation(); evt.preventDefault(); evt.originalEvent.dataTransfer.dropEffect = 'copy'; }); $('#file_drop_zone').on("drop",function(evt){ evt.stopPropagation(); evt.preventDefault(); var files = evt.originalEvent.dataTransfer.files; if(files.length != 1){ alert('1ファイルのみドロップできます'); return; } var drop_elm = evt.target; var file = files[0]; var reader = new FileReader(); reader.onload = (function(theFile) { return function(e){ file.content = e.target.result; this_obj.post_read_file(file, drop_elm); }; })(file); reader.readAsDataURL(file); //BASE64でファイルを読込み // reader.readAsArrayBuffer(file); // reader.readAsBinaryString(file); // reader.readAsText(file); }); }, // FileAPIによる読込み結果をDOMに反映 post_read_file: function(file, drop_elm){ var list_tr = $('#tmpl_droped_file').tmpl(); this.fill_in_droped_file_tr(list_tr, file ); $('#file_dropped_zone').append( list_tr ); //file.content }, fill_in_droped_file_tr: function(tr, file ){ $('.fileName', tr).html(file.name); $('.fileSize', tr).html(file.size/1000 +'KB'); $('.fileContent', tr).val(file.content); return tr; }, submit_docs: function(){ var data = { teiCode: $('#tei_code').text(), fileNames : [], fileContents : [] }; $("#file_dropped_zone tr").each(function(){ var upfile_name = $(".fileName", $(this)).text(); // reader.readAsDataURL()では先頭に余計な文字列(MIME TYPE)が // 入るので、これを削除 var upfile_content =$(".fileContent",$(this)).val().split(",")[1]; if(upfile_name && upfile_content){ data.fileNames.push(upfile_name); data.fileContents.push(upfile_content); } }); var req_url = '/DocListRest/' + data.tei_code + '/upfiles'; var this_obj = this; $.ajax({url: req_url, type: 'POST', data: data, success: function(ret_json,txt_status,xhr){ var ret_data = $.parseJSON( ret_json ); if (ret_data.result =='success'){ alert('SUCCESS'); } else { alert('FAIL'); } }, error: function(ret_json,txt_status,xhr){ alert('FAIL'); } }); }, }; window.doc_list = new DocList(); })();
サーバ側 (spring boot for java )
package jp.end0tknr.streamdoc.ctrl; import java.util.List; import java.util.Map; import java.io.File; import java.io.FileOutputStream; import java.util.Base64; import java.util.HashMap; import java.util.LinkedHashMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.ui.Model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.PutObjectRequest; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import jp.end0tknr.streamdoc.objmodel.ImageMagick; import jp.end0tknr.streamdoc.objmodel.TeiDoc; @RestController public class DocListRest { private static final Logger logger = LoggerFactory.getLogger(DocListRest.class); @Autowired private JdbcTemplate jdbcTemplate; private static final String ACCESS_KEY = "ないしょ"; private static final String SECRET_KEY = "ないしょ"; @RequestMapping(value="/DocListRest/{teiCode}/upfiles") public HashMap<String, String> upfiles ( @PathVariable String teiCode, @RequestParam("fileNames[]") List<String> fileNames, @RequestParam("fileContents[]") List<String> fileContents, Model model) { logger.info("start upfiles()"); logger.info( Regions.AP_NORTHEAST_1.toString() ); BasicAWSCredentials awsCreds = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY); AmazonS3 s3client = AmazonS3ClientBuilder.standard() .withRegion(Regions.AP_NORTHEAST_1) .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) .build(); ImageMagick imageMagick = new ImageMagick(); int i = 0; for (String fileContent : fileContents ) { String fileName = fileNames.get(i); FileOutputStream newFile; String newFilePath = "c:/home/endo/tmp/"+fileName; try { newFile = new FileOutputStream(newFilePath); newFile.write( Base64.getDecoder().decode(fileContent) ); newFile.close(); } catch (Exception e) { e.printStackTrace(); } File file = new File(newFilePath); try { logger.info( "tmp/"+fileName ); s3client.putObject(new PutObjectRequest( "test-end0tknr", "tmp/"+fileName, file)); } catch (AmazonServiceException ase) { logger.error(ase.getMessage()); } catch (AmazonClientException ace) { logger.error(ace.getMessage()); } imageMagick.convThumbnail(newFilePath); i++; } logger.info("done upfiles()"); HashMap<String,String> retVals = new HashMap<String,String>(); retVals.put("result","success"); return retVals; } }