Click here to Skip to main content
15,887,302 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I can not solve the issue with MultipartException? I try to create a new Item with adding the imges React. Every time I receive the error in Spring console, that current request is not Multipart request.

I created a form for adding the item details and images of item and added
enctype="multipart/form-data
` but it shows the Axios error
AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE', config: {…}, request: XMLHttpRequest, …


but Spring console shows me :
_Current request is not a multipart request



On spring I created two enities for Items and Images. And on Item add the images should be added together with item ID. For I can take the images from DB by Item id.

Here are the Entities:

Items Entity :

Java
package com.demo.fijinv.Models;
    
    import jakarta.persistence.*;
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.List;
    
    @Entity
    @Table(name = "assets")
    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public class Assets {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
        @Column(name = "asset_type")
        private String assettype;
        @Column(name = "asset_brand")
        private String assetBrand;
        @Column(name = "asset_model")
        private String assetModel;
    
    
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "assets")
        private List<Image> images = new ArrayList<>();
    
    
        private Long previewImageId;
        private LocalDateTime creationDate;
        @PrePersist //to read about inversion of control
        private void init() {
            creationDate = LocalDateTime.now();
        }
        public void addImageToItemName(Image image) {
            image.setAssets(this);
            images.add(image);
        }
    
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        private List<Items> invItem = new ArrayList<>();
    }


Images Entity:

Java
package com.demo.fijinv.Models;
    
    import jakarta.persistence.*;
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import java.util.List;
    @Entity
    @Table(name = "images")
    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public class Image {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
        @Column(name = "name")
        private String name;
        @Column(name = "originalFileName")
        private String originalFileName;
        @Column(name = "size")
        private Long size;
        @Column(name = "contentType")
        private String contentType;
        @Column(name = "isPreviewImage")
        private boolean isPreviewImage;
        @Column(length = 10000000)
        @Lob
        private byte[] bytes;
    
        @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
        private Assets assets;
    
        @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
        private List<Items> items;
    }


And the controllers for these entities:

Items Controller :

Java
package com.demo.fijinv.Conteollers;
    
    import com.demo.fijinv.Models.Assets;
    import com.demo.fijinv.Models.Image;
    import com.demo.fijinv.Repositories.AssetsRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.util.List;
    
    import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
    
    @CrossOrigin("*")
    @RestController
    @RequestMapping("/api/assets")
    public class AssetsController {
        @Autowired
        public AssetsRepository assetsRepository;
    
        @GetMapping
        public List<Assets> getAllAssets(){
            return assetsRepository.findAll();
        }
    
        @DeleteMapping("{id}")
        public ResponseEntity<Assets> deleteAsset(@PathVariable Long id){
            assetsRepository.deleteById(id);
            return new ResponseEntity<>(HttpStatus.OK);
        }
    
        @PostMapping(consumes = {MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
        public void saveAsset(@RequestBody Assets assets, @RequestParam("file1") MultipartFile file1, @RequestParam("file2") MultipartFile file2, @RequestParam("file3") MultipartFile file3) throws IOException {
            Image image1;
            Image image2;
            Image image3;
    
            if(file1.getSize() != 0){
                image1 = toImageEntity(file1);
                image1.setPreviewImage(true);
                assets.addImageToItemName(image1);
            }
            if(file2.getSize() != 0){
                image2 = toImageEntity(file2);
                assets.addImageToItemName(image2);
            }
            if(file3.getSize() != 0){
                image3 = toImageEntity(file3);
                assets.addImageToItemName(image3);
            }
    
            Assets itemFromDB = assetsRepository.save(assets);
            itemFromDB.setPreviewImageId(itemFromDB.getImages().get(0).getId());
            assetsRepository.save(assets);
        }
    
        private Image toImageEntity(MultipartFile file) throws IOException {
            Image image = new Image();
            image.setName(file.getName());
            image.setOriginalFileName(file.getOriginalFilename());
            image.setContentType(file.getContentType());
            image.setSize(file.getSize());
            image.setBytes(file.getBytes());
            return image;
        }
    }


Images Controller :

Java
package com.demo.fijinv.Conteollers;
    
    import com.demo.fijinv.Models.Image;
    import com.demo.fijinv.Repositories.ImageRepository;
    import lombok.RequiredArgsConstructor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.io.InputStreamResource;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    import java.io.ByteArrayInputStream;
    import java.util.List;
    
    @CrossOrigin("*")
    @RestController //no needed to present anything
    @RequestMapping("/api/assets/images")
    public class ImageController {
        @Autowired
        public ImageRepository imageRepository;
    
        @GetMapping
        private List<Image> getAllImages(){
            return imageRepository.findAll();
        }
    
        @GetMapping("{id}")
        private ResponseEntity<?> getImageByID(@PathVariable Long id){
            Image image = imageRepository.findById(id).orElse(null);
            return ResponseEntity.ok()
                    .header("filename", image.getOriginalFileName())
                    .contentType(MediaType.valueOf(image.getContentType()))
                    .contentLength(image.getSize())
                    .body(new InputStreamResource(new ByteArrayInputStream(image.getBytes())));
        }
    }


Both controllers are configured for allow the requests from all the services by adding
`@CrossOrigin("*")`
, which means that spring should receive the requests.

With React I created a simple page with form in modal where I scan add the item with images :

JavaScript
import React, { useEffect, useState } from 'react'
    import { Link } from 'react-router-dom';
    import { Modal, Button } from 'react-bootstrap'
    import AssetsSetvice from "./../../Services/AssetsService"
    
    
    const AssetsComponenet = () => {
        const [show, setShow] = useState(false);
        const modalShow = () => setShow(true);
        const modalHide = () => setShow(false);
    
        // getting all assets 
        const [assets, setAssets] = useState([]);
        useEffect(() => {
            AssetsSetvice.getAllAssets().then((res) => {
                setAssets(res.data);
            }).catch(err => {
                console.log(err)
            })
        }, []);
        const [assettype, setAssettype] = useState('');
        const [assetBrand, setAssetBrand] = useState('');
        const [assetModel, setAssetModel] = useState('');
        const [image1, setImage1] = useState();
        const [image2, setImage2] = useState();
        const [image3, setImage3] = useState();
        const [showImage1, setShowImage1] = useState();
        const [showImage2, setShowImage2] = useState();
        const [showImage3, setShowImage3] = useState();
    
        const saveAsset = (event) => {
            event.preventDefault()
            const asset = {
                assettype,
                assetBrand,
                assetModel,
                image1,
                image2,
                image3
            }
    
            console.log(asset)
            
            AssetsSetvice.addNewAsset(asset).then((res) => {
                console.log(res.data)
                event.preventDefault();
            }).catch(err => {
                console.log(err)
            })
        }
    
        const saveAndClose = (ev) => {
            saveAsset(ev);
            setShow(false);
        }
    
        const deleteAsset = (id) => {
            if (window.confirm("Are you sure want to delete this asset?")) {
                AssetsSetvice.deleteAsset(id).then((response) => {
                    console.log(`Asset with ${id} was deleted`);
                    // window.location.replace("/users");
                }).catch(error => {
                    console.log(`Something went worng : \n ${error}`);
                })
            }
        }
    
        let count = 1;
        return (
            <>
                <div className='container'>
                    <h2 className='text-center mt-4 mb-4 bold'> List of Items</h2>
                    <div className='mb-3'>
                        <button type='button' className='btn btn-primary' data-toggle="modal" onClick={modalShow} data-target="#addNewItemModal">
                            Add new Asset
                        </button>
                    </div>
                    <table className='table table-bordered table-striped'>
                        <thead>
                            <tr>
                                <th className="th-sm">№</th>
    
                                <th className="th-sm">Name</th>
                                <th className="th-sm">Brand</th>
                                <th className="th-sm">Model</th>
                                <th className="th-sm"> Action </th>
                            </tr>
                        </thead>
                        <tbody>
                            {
                                assets.map(
                                    function (item) {
                                        return <tr key={item.id}>
                                            {/* <tr> */}
                                            <th className="th-sm">{count++}</th>
                                            <th className="th-sm">Asset Name</th>
                                            <th className="th-sm">Asset Brand</th>
                                            <th className="th-sm">Asset Model</th>
                                            <th className="th-sm">
                                                {/* <Link to={`/item-delete/${item.id}`} className="btn btn-primary"> Delete Item </Link> */}
                                                <Link onClick={(id) => { deleteAsset(id) }} className="btn btn-primary"> Delete Asset </Link>
                                            </th>
                                        </tr>
                                    }
                                )
                            }
                        </tbody>
                    </table>
    
                    <Modal show={show} size='lg' onHide={modalHide} centered>
                        <Modal.Header closeButton>
                            <Modal.Title center>
                                Add New Item
                            </Modal.Title>
                        </Modal.Header>
                        <Modal.Body>
                            <div className='container-fluid'>
                                <form className='row' method='POST' enctype="multipart/form-data">
                                    {/* <form className='row' > */}
                                    <div className='col-md-4'>
                                        <label className='form-label'> Item Name </label>
                                        <input type='text'
                                            placeholder='Item Name'
                                            className='form-control'
                                            // value={itemname}
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setAssettype(e.target.value)
                                                }
                                            }}
                                            required
                                        />
                                    </div>
                                    <div className='col-md-4'>
                                        <label className='form-label'> Item Brand </label>
                                        <input type='text'
                                            placeholder='Item Brand'
                                            className='form-control'
                                            // value={itembrand} 
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setAssetBrand(e.target.value)
                                                }
                                            }}
                                            required
                                        />
                                    </div>
                                    <div className='col-md-4'>
                                        <label className='form-label'> Item Model </label>
                                        <input type='text'
                                            placeholder='Item Model'
                                            className='form-control'
                                            // value={itemmodel}
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setAssetModel(e.target.value)
                                                }
                                            }}
                                            required
                                        />
                                    </div>
    
                                    <div className='col-md-4'>
                                        <label className='form-label'> First Image </label>
                                        <input type='file'
                                            className='form-control'
                                            // value={file1}
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setShowImage1(URL.createObjectURL(e.target.files[0]))
                                                    setImage1(e.target.files[0])
                                                }
                                            }}
                                        />
                                    </div>
                                    <div className='col-md-4'>
                                        <label className='form-label'> First Image </label>
                                        <input type='file'
                                            className='form-control'
                                            // value={file2}
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setShowImage2(URL.createObjectURL(e.target.files[0]))
                                                    setImage2(e.target.files[0])
                                                }
                                            }}
                                            required
                                        />
                                    </div>
                                    <div className='col-md-4'>
                                        <label className='form-label'> First Image </label>
                                        <input type='file'
                                            className='form-control'
                                            // value={file3}
                                            onChange={(e) => {
                                                if (e.target.value != "") {
                                                    setShowImage3(URL.createObjectURL(e.target.files[0]))
                                                    setImage3(e.target.files[0])
                                                }
                                            }}
                                        />
                                    </div>
                                </form>
                            </div>
                            <div className='row mt-4'>
                                <div className='col-md-4'>
                                    <img style={{ width: "150px" }} className="rounded mx-auto d-block" src={showImage1} />
                                </div>
                                <div className='col-md-4'>
                                    <img style={{ width: "150px" }} className="rounded mx-auto d-block" src={showImage2} />
                                </div>
                                <div className='col-md-4'>
                                    <img style={{ width: "150px" }} className="rounded mx-auto d-block" src={showImage3} />
                                </div>
                            </div>
                        </Modal.Body>
                        <Modal.Footer center>
                            <Button center onClick={(e) => { saveAndClose(e) }} variant="primary">Add New Asset</Button>
                        </Modal.Footer>
                    </Modal>
    
                </div>
            </>
        )
    }
    
    export default AssetsComponenet



As you can see that in the form there is encription type - multipart:
`<form className='row' method='POST' enctype="multipart/form-data">`
but any way I receive the error.

I use Axios for receive the data from backend, and I created the service for Items:

JavaScript
import axios from "axios";
    
    const ASSETS_GOT_FROM_REST_API = "http://localhost:8082/api/assets";
    const IMAGES_GOT_FROM_REST_API = "http://localhost:8082/api/assets/images";
    
    
    class AssetsSetvice {
        getAllAssets() {
            return axios.get(ASSETS_GOT_FROM_REST_API);
        }
        addNewAsset(asset) {
            return axios.post(ASSETS_GOT_FROM_REST_API, asset);
        }
        deleteAsset(assetId) {
            return axios.delete(ASSETS_GOT_FROM_REST_API + "/" + assetId);
        }
    
        getAllImages() {
            return axios.get(IMAGES_GOT_FROM_REST_API);
        }
        addNewImages(images) {
            return axios.addNewImage(IMAGES_GOT_FROM_REST_API, images);
        }
    
    }
    
    export default new AssetsSetvice();


when I try to console log the item, which I try to add, I receive :
assetBrand : "fgdfgerg"
   assetModel : "gvcvbdxbt"
   assettype : "rterte"
   file1 : File {name: 'lenovo-3.jpg', lastModified: 1684826589057, lastModifiedDate: Tue May 24 2023 10:23:09 GMT+0300 (Eastern European Summer Time), webkitRelativePath: '', size: 4437, …}
   file2 : File {name: 'm700-1.jfif', lastModified: 1684826441152, lastModifiedDate: Tue May 24 2023 10:20:41 GMT+0300 (Eastern European Summer Time), webkitRelativePath: '', size: 3221, …}
   file3 : File {name: 'm700-1.jfif', lastModified: 1684826441152, lastModifiedDate: Tue May 23 2023 10:20:41 GMT+0300 (Eastern European Summer Time), webkitRelativePath: '', size: 3221, …}


seams that I am able to send the post request to server, but server refuse it.
And I tried by the different ways.

What I do wrong? How can I solve tis issue?
Can it be related with ManyToOne or OneToMany which were configured in Entity calsses? Because I dont see any other problems.... seams that something blocking in backend side...

What I have tried:

I tried different ways, which i found in internet, to solve the issue.
I tried post with FormData, or postForm with a FileList but I receive the error in Spring console :

Content-Type 'multipart/form-data;boundary=----WebKitFormBoundaryHIWDkpresxefAeyx;charset=UTF-8' is not supported
Posted
Updated 24-May-23 0:49am
v2

1 solution

 
Share this answer
 
Comments
Артём Орёл 24-May-23 6:27am    
I have already tried to do by this way, but I receive the error : Content-Type 'multipart/form-data;boundary=----WebKitFormBoundaryHIWDkpresxefAeyx;charset=UTF-8' is not supported
Richard Deeming 24-May-23 6:36am    
That's not what the code in your question shows. Based on what you've shown, you haven't tried either of the methods shown in that document (post with FormData, or postForm with a FileList).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900