spring - Spring Controller - 测试以使用邮递员在内部接收带有 multipartfile 的嵌套 dto
问题描述
我正在开发一个接受 POST 方法中的 DTO 并基于该 DTO 创建实体的服务。嵌套在里面的是一个多部分文件,它将是将要创建的实体使用的图像。
使用邮递员测试我的后端,我不断收到一个看似空的 DTO。控制器内部的三个日志分别返回null
,0
和null
。
这就是我设置数据的方式,我很确定这是问题所在:
我将图像转换为 base64 字符串,据我所知,这是发布嵌套图像的唯一方法。
代码
控制器
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<InventoryComponentDto> create(@ModelAttributee InventoryComponentDto request) {
System.out.println(request.getDescription());
System.out.println(request.getMinimal_supply());
System.out.println(request.getComponent());
InventoryComponentDto result = inventoryComponentService.create(request);
if (result == null) {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok(result);
}
InventoryComponentDto
public class InventoryComponentDto {
private ComponentDto component;
private String description;
private Date createdAt;
private Date updatedAt;
private int minimal_supply;
private int supply;
}
组件Dto
public class ComponentDto {
private Long id;
private int number;
private String name;
private FileDto image;
}
文件Dto
public class FileDto {
private String name;
private String type;
private String url;
private MultipartFile data;
}
我在邮递员中充分创建我的 dto 的方法是什么,包括图像?
更新
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.package.MCI.dto.InventoryComponentDto[\"component\"]->com.package.MCI.dto.ComponentDto[\"image\"])",
"trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: (was java.lang.NullPointerException); nested...
解决方案
您需要创建一个自定义杰克逊反序列化器。
//CustomDeserializer
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
public class CustomDeserializer extends StdDeserializer<FileDTO> {
public CustomDeserializer() {
super(FileDTO.class);
}
protected CustomDeserializer(Class<?> vc) {
super(vc);
}
@Override
public FileDTO deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
String name = node.get("name").asText();
String url = node.get("url").asText();
String type = "." + node.get("type").asText();
String fileBase64 = node.get("data").asText();
byte[] fileBytes = Base64Utils.decodeFromString(fileBase64);
FileItem fileItem = new DiskFileItem(name, "image/jpg", false, name + type,
fileBytes.length, null);
fileItem.getOutputStream().write(fileBytes);
fileItem.getOutputStream().flush();
MultipartFile file = new CommonsMultipartFile(fileItem);
fileItem.getOutputStream().close();
FileDTO fileDTO = new FileDTO();
fileDTO.setName(name);
fileDTO.setUrl(url);
fileDTO.setType(type);
fileDTO.setData(file);
return fileDTO;
}
}
并像这样使用它:
//FileDTO
@JsonDeserialize(using = CustomDeserializer.class)
public class FileDTO {
您需要这两个依赖项:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
推荐阅读
- java - 验证 Pre-Order Binary Search Tree 表达式的语法
- java - Java Spark 删除重复项/空值并保留顺序
- java - 使用来自 (BluetoothGattCharacteristic)characteristic.getValue() 的数据创建、写入和保存 csv 文件
- bash - 检查RDS的状态
- google-play - Google Play 控制台 - 将版本升级到生产版本是否会使现有的已审核但尚未发布的生产版本失效?
- mysql - “使用 db_name”在 MySQL 上失败,错误 #1046,消息 =“未选择数据库”
- angular - 无法使用带有角度8的xlsx的json数据导出到excel
- android - kotlin 使用 for 循环在 2 个 imageview 之间选择 n 次
- google-sheets - 多个单元格的相关下拉列表,如何
- java - 如何计算我们刚刚输入的最后一个数字?