Java側のコードに問題があるようです。Vue側については開発経験があまり無いのと提示されているコードが断片的なのでよくわかりません。
とりあえず、動作確認できたサンプルコードを下記に提示しますのでご参考になれば幸いです。
サンプルコード (Spring Boot)
ポストされたファイルを受け取るには@RequestBody MultipartFile
ではなく、@RequestParam("file") MultipartFile
である必要があります。
環境
- OpenJDK 13.0.1
- Spring Boot 2.2.1
アプリケーションのエンドポイントはhttp://localhost:8080/upload
です。
アップロードされた画像ファイルをBase64エンコードしてレスポンスします。
Java
1@CrossOrigin(origins = "http://localhost:3000")
2@PostMapping(value = "/upload", produces = MediaType.APPLICATION_JSON_VALUE)
3public ResponseEntity<Map<String, String>> fileUpload(@RequestParam("name") String name,
4 @RequestParam("file") MultipartFile uploadFile) throws Exception {
5
6 if (uploadFile.isEmpty()) {
7 return ResponseEntity.badRequest().build();
8 }
9
10 log.info("name:{}", name);
11 log.info("uploadFile name:{}", uploadFile.getOriginalFilename());
12 log.info("uploadFile size:{}", uploadFile.getSize());
13
14 byte[] image = uploadFile.getBytes();
15 String base64EncodedImage = "data:image/jpeg;base64," + new String(Base64.encodeBase64(image), StandardCharsets.US_ASCII);
16 Map<String, String> res = Map.of("base64", base64EncodedImage, "name", name);
17
18 return ResponseEntity.ok(res);
19}
動作確認コマンド
demo.jpgという画像ファイルをエンドポイントへpostできるかcurlで動作確認します。このようにバックエンド側だけでテストしてみて、問題がフロントとバンクエンドのどちらにあるか切り分けます。
curl -v -X POST "localhost:8080/upload" -F "name=demo.jpg" -F "file=@demo.jpg;type=image/jpg"
postが成功すると下記のjsonオブジェクトがレスポンスされます。
{"base64":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDA ...省略... igD/2Q==","name":"demo.jpg"}
サンプルコード (Nuxt.js)
環境
コンポーネント
pages/fileupload.vue
Vue
1<template>
2
3 <div>
4 <form>
5 <input @change="uploadFile" type="file" name="file" />
6 </form>
7 </div>
8 <div v-for="(file, i) in files" :key="i">
9 <span>{{ i }} - {{ file.name }}</span>
10 <img :src="file.image" />
11 </div>
12
13</template>
14
15<script>
16import { mapState, mapActions } from 'vuex'
17
18export default {
19 computed: {
20 ...mapState({
21 files: (state) => state.fileupload.files
22 })
23 },
24 methods: {
25 ...mapActions({
26 uploadFile: 'fileupload/uploadFile'
27 })
28 }
29}
30</script>
vuex
store/fileupload.js
JavaScript
1export const state = () => ({
2 files: []
3})
4
5export const actions = {
6 async uploadFile(context, event) {
7 const file = (event.target.files || event.dataTransfer.files)[0]
8
9 const formData = new FormData()
10 formData.append('name', file.name)
11 formData.append('file', file)
12
13 const response = await this.$axios
14 .post('http://localhost:8080/upload', formData, {
15 headers: { 'Content-Type': 'multipart/form-data' }
16 })
17 .then((response) => {
18 context.commit('add', {
19 name: response.data.name,
20 image: response.data.base64
21 })
22 })
23 .catch((error) => {
24 return error.response
25 })
26
27 return response
28 }
29}
30
31export const mutations = {
32 add(state, payload) {
33 state.files.push({
34 name: payload.name,
35 image: payload.image
36 })
37 }
38}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/06 23:46