首页 > 解决方案 > 如何在同一个 POST 请求中发送 JSON 和图像并将其级联?弹簧靴

问题描述

我有一个名为“Bga”的实体,它有一个图像列表。我正在尝试创建一个 Bga 通过 JSON 发送其数据,并且在同一个请求中我想上传一个图像,所以我可以级联它并且数据库中的表“图像”将具有来自 Bga 和 Bga 的外键将有它的图像列表

我在做什么:

发送多部分表单: 在此处输入图像描述

其中包含来自实体 Bga 的 JSON 数据: 在此处输入图像描述

第二个条目是我上传的图像

我可以单独创建 Bga 并上传图像,但我不知道如何以可以级联的方式进行操作。

POST 请求

@PostMapping
    @ResponseBody
    public ResponseEntity<Bga> createBga(@RequestPart("bga") Bga bga, @RequestPart("file") MultipartFile file) throws IOException {

        fileStorage.save(file);

        bgaRepository.save(bga);

        return ResponseEntity.status(HttpStatus.OK).body(bga);
    }

然后是上传图片的服务

@Service
public class FileStorageService {
    
    @Autowired
    private ImagemRepository imagemRepository;

public Imagem save(MultipartFile file) throws IOException {
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());
        Imagem Imagem = new Imagem(fileName, file.getContentType(), file.getBytes());

        return imagemRepository.save(Imagem);
    }

}

我正在为两者使用 JPA 存储库

实体 Bga:

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;


@Entity
@Table(name="BGA")
public class Bga implements Serializable {
    
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id_bga;
    
    
    private String nome;
    
    private int num_bga;
    

    @OneToMany(mappedBy = "bga", cascade = CascadeType.ALL)
    private List<Imagem> imagens;
    
    public Bga() {
        
    }


    

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getNum_bga() {
        return num_bga;
    }

    public void setNum_bga(int num_bga) {
        this.num_bga = num_bga;
    }

    public long getId_bga() {
        return id_bga;
    }

    public void setId_bga(long id_bga) {
        this.id_bga = id_bga;
    }

    public List<Imagem> getImagens() {
        return imagens;
    }

    public void setImagens(List<Imagem> imagens) {
        this.imagens = imagens;
    }

和实体图像:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;


@Entity
public class Imagem {
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id_imagem;

    private String name;

    private String type;

    @Lob
    private byte[] imagem;

    @ManyToOne
    @JoinColumn(name = "id_bga", referencedColumnName = "id_bga")
    private Bga bga;

public Imagem() {

    }
    
    public Long getId_imagem() {
        return id_imagem;
    }

    public void setId_imagem(Long id_imagem) {
        this.id_imagem = id_imagem;
    }

    public byte[] getImagem() {
        return imagem;
    }

    public void setImagem(byte[] imagem) {
        this.imagem = imagem;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Imagem(String name, String type, byte[] imagem) {
        this.name = name;
        this.type = type;
        this.imagem = imagem;
    }

    public Bga getBga() {
        return bga;
    }

    public void setBga(Bga bga) {
        this.bga = bga;
    }

但是我做 Bga 的方式没有得到上传的图像

在此处输入图像描述

如何以我可以级联的方式进行操作,因此表 Image 将具有来自 bga 的外键?

标签: javaspringspring-boothibernatejpa

解决方案


小心交易边界。您希望 1 个事务存储一个文件 + BGA,因此:

  1. 使用带有文件和 bga 的事务方法创建 @Service
  2. 将 FileStorageService 和 BgaRepository 自动装配到服务中
  3. 运行fileStorage.save(file)bgaRepository.save(bga)以该方法,然后在 Imagem 上设置 bga

扩展您的 FileStorageService 以获取 Bga 对象:

@Service
public class FileStorageService {

    @Autowired
    private ImagemRepository imagemRepository;
    @Autowired // NEW
    private BgaRepository bgaRepository; // NEW

    @Transactional // NEW
    public Imagem save(Bga bga, MultipartFile file) throws IOException {
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());
        Imagem Imagem = new Imagem(fileName, file.getContentType(), file.getBytes());

        bgaRepository.save(bga); // NEW
        Imagem.setBga(bga); // NEW

        return imagemRepository.save(Imagem);
    }
}

在您的控制器中,仅使用两个 DTO 调用 1 个服务:

@PostMapping
@ResponseBody
public ResponseEntity<Bga> createBga(@RequestPart("bga") Bga bga, @RequestPart("file") MultipartFile file) throws IOException {

    fileStorage.save(bga, file); // NEW: passing in 'bga' here

    // bgaRepository.save(bga); .. DELETED

    return ResponseEntity.status(HttpStatus.OK).body(bga);
}

推荐阅读