当前请求不是多部分请求 Spring Boot 和 Postman(上传 json 文件加上额外字段)
Current request is not a multipart request Spring Boot and Postman (Uploading json file plus extra field)
我在尝试为我的请求上传 json 文件和额外的 id 或 dto 对象时遇到此 Current request is not a multipart request
错误,因为这也是填充我的数据库所必需的。
当我只发送 json 文件时,一切都正常上传,但现在我已经将 id 字段添加到相关方法和 Postman 中,我收到此消息并正在努力调试并修复它,如果我能得到任何帮助,请。
这些是涉及的部分:
@Controller
@RequestMapping("/api/gatling-tool/json")
public class StatsJsonController {
@Autowired
StatsJsonService fileService;
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
String message = "";
UUID id = categoryQueryDto.getId();
if (StatsJsonHelper.hasJsonFormat(file)) {
try {
fileService.save(file, id);
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
message = "Please upload a json file!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}
}
@Service
public class StatsJsonService {
@Autowired
StatsJsonRepository repository;
public void save(MultipartFile file, UUID id) {
StatsEntity statsEntity = StatsJsonHelper.jsonToStats(file, id);
repository.save(statsEntity);
}
}
public class StatsJsonHelper {
public static String TYPE = "application/json";
public static boolean hasJsonFormat(MultipartFile file) {
if (!TYPE.equals(file.getContentType())) {
return false;
}
return true;
}
public static StatsEntity jsonToStats(MultipartFile file, UUID id) {
try {
Gson gson = new Gson();
File myFile = convertMultiPartToFile(file);
BufferedReader br = new BufferedReader(new FileReader(myFile));
Stats stats = gson.fromJson(br, Stats.class);
StatsEntity statsEntity = new StatsEntity();
statsEntity.setGroup1Count(stats.stats.group1.count);
statsEntity.setGroup1Name(stats.stats.group1.name);
statsEntity.setGroup1Percentage(stats.stats.group1.percentage);
statsEntity.setId(id);
return statsEntity;
} catch (IOException e) {
throw new RuntimeException("fail to parse json file: " + e.getMessage());
}
}
非常感谢。
https://github.com/francislainy/gatling_tool_backend/pull/3/files
更新
根据@dextertron 的回答添加了更改(出现 415 不受支持的媒体类型错误)
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
即使我也将此部分从 application/json 更改为 multiform/data,同样的错误仍然存在。
public static String TYPE = "multiform/data";
首先,您需要将 Content-Type headers 设置为“multipart/form-data”,然后作为 form-data 中的第二个参数,使用“categoryQueryDto”作为键和添加 json 作为值 ({'id': 'whatever'}).
之后,将控制器中的参数注释从@RequestPart/@RequestBody 更改为@RequestParam。
我在控制器中尝试了几个组合。
为我工作的那个看起来像这样。
基本上我们必须将两个参数都作为 @RequestParam
.
传递
@PostMapping("/import")
public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String id) {
return null;
}
我知道你想将 CategoryQueryDto
作为 @RequestBody
传递,但在多部分请求中似乎 @RequestParam
和 @RequestBody
似乎不能一起工作。
所以你在我看来你可以在这里做两件事:-
像上面那样设计控制器,只需将id
作为字符串发送到请求中并直接在fileService.save(file, id);
中使用。
如果您仍想使用 CategoryQueryDto
,您可以发送此 {"id":"adbshdb"}
,然后使用 object 映射器将其转换为 CategoryQueryDto
。
这就是你的控制器的样子 -
@PostMapping("/import")
public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String categoryQueryDtoString) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
CategoryQueryDto categoryQueryDto = objectMapper.readValue(categoryQueryDtoString, CategoryQueryDto.class);
// Do your file related stuff
return ResponseEntity.ok().body(file.getOriginalFilename());
}
这就是使用 postman/ARC -
发送请求的方法
发布我试验过的另一个解决方案,即将 id 附加到调用路径。
@PostMapping(value = "/import/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @PathVariable(value = "id") UUID id) {
String message = "";
if (StatsJsonHelper.hasJsonFormat(file)) {
try {
fileService.save(file, id);
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
message = "Please upload a json file!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}
我在尝试为我的请求上传 json 文件和额外的 id 或 dto 对象时遇到此 Current request is not a multipart request
错误,因为这也是填充我的数据库所必需的。
当我只发送 json 文件时,一切都正常上传,但现在我已经将 id 字段添加到相关方法和 Postman 中,我收到此消息并正在努力调试并修复它,如果我能得到任何帮助,请。
这些是涉及的部分:
@Controller
@RequestMapping("/api/gatling-tool/json")
public class StatsJsonController {
@Autowired
StatsJsonService fileService;
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
String message = "";
UUID id = categoryQueryDto.getId();
if (StatsJsonHelper.hasJsonFormat(file)) {
try {
fileService.save(file, id);
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
message = "Please upload a json file!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}
}
@Service
public class StatsJsonService {
@Autowired
StatsJsonRepository repository;
public void save(MultipartFile file, UUID id) {
StatsEntity statsEntity = StatsJsonHelper.jsonToStats(file, id);
repository.save(statsEntity);
}
}
public class StatsJsonHelper {
public static String TYPE = "application/json";
public static boolean hasJsonFormat(MultipartFile file) {
if (!TYPE.equals(file.getContentType())) {
return false;
}
return true;
}
public static StatsEntity jsonToStats(MultipartFile file, UUID id) {
try {
Gson gson = new Gson();
File myFile = convertMultiPartToFile(file);
BufferedReader br = new BufferedReader(new FileReader(myFile));
Stats stats = gson.fromJson(br, Stats.class);
StatsEntity statsEntity = new StatsEntity();
statsEntity.setGroup1Count(stats.stats.group1.count);
statsEntity.setGroup1Name(stats.stats.group1.name);
statsEntity.setGroup1Percentage(stats.stats.group1.percentage);
statsEntity.setId(id);
return statsEntity;
} catch (IOException e) {
throw new RuntimeException("fail to parse json file: " + e.getMessage());
}
}
非常感谢。
https://github.com/francislainy/gatling_tool_backend/pull/3/files
更新
根据@dextertron 的回答添加了更改(出现 415 不受支持的媒体类型错误)
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
即使我也将此部分从 application/json 更改为 multiform/data,同样的错误仍然存在。
public static String TYPE = "multiform/data";
首先,您需要将 Content-Type headers 设置为“multipart/form-data”,然后作为 form-data 中的第二个参数,使用“categoryQueryDto”作为键和添加 json 作为值 ({'id': 'whatever'}).
之后,将控制器中的参数注释从@RequestPart/@RequestBody 更改为@RequestParam。
我在控制器中尝试了几个组合。
为我工作的那个看起来像这样。
基本上我们必须将两个参数都作为 @RequestParam
.
@PostMapping("/import")
public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String id) {
return null;
}
我知道你想将 CategoryQueryDto
作为 @RequestBody
传递,但在多部分请求中似乎 @RequestParam
和 @RequestBody
似乎不能一起工作。
所以你在我看来你可以在这里做两件事:-
像上面那样设计控制器,只需将
id
作为字符串发送到请求中并直接在fileService.save(file, id);
中使用。如果您仍想使用
CategoryQueryDto
,您可以发送此{"id":"adbshdb"}
,然后使用 object 映射器将其转换为CategoryQueryDto
。
这就是你的控制器的样子 -
@PostMapping("/import")
public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String categoryQueryDtoString) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
CategoryQueryDto categoryQueryDto = objectMapper.readValue(categoryQueryDtoString, CategoryQueryDto.class);
// Do your file related stuff
return ResponseEntity.ok().body(file.getOriginalFilename());
}
这就是使用 postman/ARC -
发送请求的方法发布我试验过的另一个解决方案,即将 id 附加到调用路径。
@PostMapping(value = "/import/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @PathVariable(value = "id") UUID id) {
String message = "";
if (StatsJsonHelper.hasJsonFormat(file)) {
try {
fileService.save(file, id);
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
message = "Please upload a json file!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}