当我尝试在react中上传一个图像,并将其发送到一个spring Boot API以将文件保存到一个数据库中时,我在spring boot中得到以下错误:
2022-12-04 03:25:28.610 WARN 15080 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'image' is not present]
2022-12-04 03:25:28.631 WARN 15080 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.LinkedHashMap<java.lang.String,java.util.List<java.lang.String>>` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.LinkedHashMap<java.lang.String,java.util.List<java.lang.String>>` from Array value (token `JsonToken.START_ARRAY`)<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 1]]
我不知道如何解决这个问题。我已经试着四处寻找,但还没有找到任何答案。我也不确定问题是在我的React代码或在我的springboot代码。
我认为我的错误是在reactjs,因为我看到在其他职位的人有一些相同的问题,他们的问题一直是他们的React代码.但我还没有弄清楚到底是什么可能是错误的React代码.我也张贴我的Spring Boot 代码的情况下,你可能想看看它,我的React代码:
const FileUpload = () => {
const link = "http://localhost:8080/uploadimage?key"
var formData = new FormData()
const [fileName, setFilename] = useState("")
const [tags, setTags] = useState([])
{/* THIS IS CODE FOR SELECTING A FILE TO UPLOAD*/}
{/* IM TRYING TO DEFINE IMAGE BY PUTTING IT IN QUOTES IN FROMDATA.APPEND */}
const handleFile = (e) => {
setFilename(e.target.files[0].name)
console.log("handle file")
console.log(e.target.files[0])
formData.append("image", e.target.files[0])
}
const uploadFile = (e) => {
{/* THIS IS CODE FOR FILE UPLOADING*/}
console.log("sending...")
console.log(formData)
axios.post(
link,
formData, {
header: {
'Content-Type': 'multipart/form-data'
}
})
.then(res => {
console.log(res.data)
})
.catch(error => {
console.log(error)
})
{/* THIS IS CODE FOR SOMETHING ELSE; SOME TAGHANDLING */}
setTimeout(3000)
const taglink = "http://localhost:8080/givetags/" + fileName;
axios.post(taglink, tags)
.then(res => (
console.log(res.data)
))
}
{/* THIS IS CODE IS ALSO FOR SOMETHING ELSE*/}
function updateTags(e) {
const log = {...tags}
log[e.target.id] = e.target.value.split(" ")
setTags(log)
}
return (
<div>
<Container>
<Card.Title className='text-center mb-3'>Upload File</Card.Title>
<Form.Group controlId='file' className='mb-3'>
<Form.Control type='file' onChange={(e) => handleFile(e)}></Form.Control>
</Form.Group>
<Form.Group controlId='tags' className='mb-3'>
<Form.Control onChange={(e) => updateTags(e)} type="text" placeholder='Write tags'></Form.Control>
</Form.Group>
<Button onClick={(e) => uploadFile(e)}>Upload File</Button>
</Container>
<TagsConvention></TagsConvention>
</div>
)
}
export default FileUpload
这是我的springboot代码:控制器:
@RestController
public class FileController {
@Autowired
private ImageServiceImpl service;
//==========================For uploading a file======================================
@CrossOrigin(origins = "http://localhost:3000")
@PostMapping("/uploadimage")
public ResponseEntity<?> uploadImage(@RequestParam("image") MultipartFile file) throws IOException {
String uploadImage = service.uploadImage(file);
return ResponseEntity.status(HttpStatus.OK)
.body(uploadImage);
}
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/getimage/{fileName}")
public ResponseEntity<?> downloadImage(@PathVariable String fileName){
byte[] file=service.downloadImage(fileName);
System.out.println(file);
return ResponseEntity.status(HttpStatus.OK)
.contentType(MediaType.valueOf(service.getType(fileName)))
.body(file);
}
@CrossOrigin(origins = "http://localhost:3000")
@PostMapping("/givetags/{fileName}")
public ImageData giveImagetags(@PathVariable String fileName, @RequestBody Map<String, List<String>> tags) {
//return service.giveImageTags(fileName, tags);
//return service.giveImageTags(fileName, tags);
System.out.println(tags);
List<String> tagList = tags.get("tags");
return service.giveImageTags(fileName, tagList);
}
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/getallimages")
public List<String> getAllImages() {
return service.getAllImages();
}
}
我的形象模型:
@Entity
@Table(name = "ImageData")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ImageData implements Image{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long imageDataId;
private String name;
private String type;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name="file_has_tag",
joinColumns = {@JoinColumn(name="image_data_id")},
inverseJoinColumns = {@JoinColumn(name = "tag_id")})
@JsonIgnoreProperties("image_data")
private Set<Tag> tags;
@Lob
@Column(name = "image_data",length = 1000)
private byte[] data;
@Override
public String toString() {
return "ImageData{" +
"imageDataId=" + imageDataId +
", name='" + name + '\'' +
", type='" + type + '\'' +
", tags=" + tags +
'}';
}
}
上传文件的服务功能:
public String uploadImage(MultipartFile file) throws IOException {
ImageData imageData = imageDataRepository.save(ImageData.builder()
.name(file.getOriginalFilename())
.type(file.getContentType())
.data(ImageUtils.compressImage(file.getBytes())).build()); //"data" is from the model class
System.out.println(imageData.toString());
if (imageData != null) {
return "file uploaded successfully : " + file.getOriginalFilename();
}
return null;
}
用于压缩图像的utils类中的函数
public static byte[] compressImage(byte[] data) {
Deflater deflater = new Deflater();
deflater.setLevel(Deflater.BEST_COMPRESSION);
deflater.setInput(data);
deflater.finish();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] tmp = new byte[4*1024];
while (!deflater.finished()) {
int size = deflater.deflate(tmp);
outputStream.write(tmp, 0, size);
}
try {
outputStream.close();
} catch (Exception ignored) {
}
return outputStream.toByteArray();
}
我试过改变formdata的值,以及fromdata.append中“image”的键,但我还没有弄清楚。我也试过搜索问题,但人们遇到的语法问题与我不同,所以我不知道可能是什么问题。
1条答案
按热度按时间dwbf0jvd1#
有两个问题:
(1)所需的请求部分“image”不存在,问题应该是参数名称问题,@RequestParam(“image”)前缀必须是“image”。您可以检查某些参数名称是否为image。
(2)JSON解析错误:在我看来,问题的主要原因是API:givetags,@RequestBody Map〈String,List〉标签,在接收react参数时无法正确翻译。您可以尝试使用List来接收参数。