You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot新闻应用一对一关联实体的MultipartFile上传问题

Spring Boot 一对一关联下消息与图片同时上传异常问题

我正在使用Spring Boot开发一款新闻应用,其中Message实体与Image实体为一对一关联关系。单独上传两者没有问题,但尝试同时上传时无法正常工作。

相关代码

Image实体类

@Entity
@Table(name = "images")
public class Image {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    @Column
    private String name;

    @Column
    private String type;

    @Lob
    @Column
    private byte[] data;

    @OneToOne(mappedBy = "image")
    private Message message;

    // getters and setters
}

Message实体类

@Entity
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, name = "published_at")
    private LocalDateTime publishedAt;

    @Column(nullable = false, length = 100)
    private String title;

    @Column(nullable = false, length = 500)
    private String summary;

    @Column(nullable = false, length = 10000)
    private String text;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "file_id", referencedColumnName = "id")
    private Image image;
    
    // getters and setters
}

MessageInquiryDto类

public class MessageInquiryDto {

    private Long id;
    @NotNull(message = "Title must not be null")
    private String title;

    @NotNull(message = "Summary must not be null")
    private String summary;

    @NotNull(message = "Text must not be null")
    private String text;

    private Image image;
    // getters and setters
}

ImageStorageService的store方法

public Image store(MultipartFile file) throws IOException {
        String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
        Image image = new Image(fileName, file.getContentType(), file.getBytes());

        return imageRepository.save(image);
    }

尝试的解决方案及问题

最初的创建接口

我最初编写的创建接口同时接收JSON格式的消息和MultipartFile文件:

@PostMapping("/messages")
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "Publish a new message with a file", security = @SecurityRequirement(name = "apiKey"))
public DetailedMessageDto create(@Valid @RequestBody MessageInquiryDto messageDto, @RequestParam(value = "file") MultipartFile file) {
    Image image = imageStorageService.store(file);
    messageDto.setImage(image);
    
    return messageMapper.messageToDetailedMessageDto(
            messageService.publishMessage(messageMapper.messageInquiryDtoToMessage(messageDto)));
}

但无法通过Postman发送请求,因为消息需要以JSON形式发送,而文件是MultipartFile类型,两者无法同时通过@RequestBody和@RequestParam正确接收。

拆分Post和Put接口的尝试

之后我尝试拆分接口,先创建消息再通过Put接口添加图片:

Put接口代码

@PutMapping("/{id}")
@Operation(summary = "Add image to a message", security = @SecurityRequirement(name = "apiKey"))
public DetailedMessageDto addImage(@PathVariable Long id, @RequestParam("file") MultipartFile file) {
    try {
        Image image = storageService.storeWithMessage(file, id);
        Message message = messageService.findOne(id);
        message.setImage(image);
        return messageMapper.messageToDetailedMessageDto(messageService.publishMessage(message));
    } catch (Exception e) {
        throw new RuntimeException("Could not upload the file: " + file.getOriginalFilename(), e);
    }
}

storeWithMessage方法代码

public Image storeWithMessage(MultipartFile file, Long id) throws IOException {
    String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
    Image image = new Image(fileName, file.getContentType(), file.getBytes());

    Optional<Message> message = messageRepository.findById(id);

    message.ifPresent(value -> value.setImage(image));
    message.ifPresent(messageRepository::save);

    return imageRepository.save(image);
}

但此时出现错误:"Unable to upload name_of_file.jpeg"。

内容的提问来源于stack exchange,提问作者Nikola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:24:56