java - 如何在同一个 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 的外键?
解决方案
小心交易边界。您希望 1 个事务存储一个文件 + BGA,因此:
- 使用带有文件和 bga 的事务方法创建 @Service
- 将 FileStorageService 和 BgaRepository 自动装配到服务中
- 运行
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);
}
推荐阅读
- swift - URLSession:遵循来自 Google 电子表格的重定向
- angular - 在 Firebase 中调用 user.getIdTokenResult(true) 会导致所有文档侦听器再次返回最新数据
- python - 我想列出列表的一部分并列出一个属性
- excel - 基于单元格条件逐行应用条件格式
- javascript - 用户单击按钮后如何使文本变为粗体?
- python - 如何使重复的线条在 Plotly 中可见
- mysql - Sequelize - 表中的 2 个可选外键
- firefox - 响应式 Vue 数据不在 Firefox 列中呈现
- arrays - 使用数组排序对多个键上的对象数组进行排序
- javascript - 如何在 React/NextJS 中嵌入第三方弹出按钮脚本