英文:
Current request is not a multipart request Spring Boot and Postman (Uploading json file plus extra field)
问题
@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());
}
}
}
UPDATE
Added changes as per @dextertron's answers (getting a 415 unsupported media type error)
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
The same error persists even if I change this part from application/json
to multiform/data
as well.
public static String TYPE = "multiform/data";
英文:
I'm getting this Current request is not a multipart request
error when trying to upload a json file and an extra id or dto object for my request, since this is also required to populate my database.
When I am sending only the json file, everything is being uploaded fine, but now I've added the id field to the related methods and Postman, I'm getting this message and struggling to debug and fix it, if I can get any help please.
These are the pieces involved:
@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());
}
}
Thank you very much.
https://github.com/francislainy/gatling_tool_backend/pull/3/files
UPDATE
Added changes as per @dextertron's answers (getting a 415 unsupported media type error)
@PostMapping(value = "/import")
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file, @RequestBody CategoryQueryDto categoryQueryDto) {
The same error persists even if I change this part from application/json to multiform/data as well.
public static String TYPE = "multiform/data";
答案1
得分: 4
以下是您要翻译的内容:
我在控制器中尝试了几种组合。
对我有效的一个看起来是这样的。
基本上,我们需要将两个参数都作为@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"}
,然后使用对象映射将其转换为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);
// 进行与文件相关的操作
return ResponseEntity.ok().body(file.getOriginalFilename());
}
这是您可以使用Postman/ARC发送请求的方式:
PS:不要忘记设置Content-Type标头,如下所示:
英文:
I tried with couple of combinations in controller.
The one Worked for me looks something like this.
Basically we will have to pass both arguments as @RequestParam
.
@PostMapping("/import")
public ResponseEntity<Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String id) {
return null;
}
I know you wanted to pass CategoryQueryDto
as @RequestBody
But it seems in multipart request @RequestParam
and @RequestBody
doesn't seem to work together.
So you IMO you can do 2 things here :-
-
Design the controller as above and just send the
id
as string in request and use that infileService.save(file, id);
directly.
-
If you still want to use
CategoryQueryDto
you can send this{"id":"adbshdb"}
and then convert it toCategoryQueryDto
using object mapper.
This is how your controller will look like -
@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());
}
And this is how you can send request using postman/ARC -
答案2
得分: 2
首先,您需要将 Content-Type 标头设置为 "multipart/form-data",然后在 form-data 的第二个参数中,使用 "categoryQueryDto" 作为键,并将 JSON 对象作为值添加({'id': 'whatever'})。
之后,将控制器中参数的注解从 @RequestPart/@RequestBody 更改为 @RequestParam。
英文:
First, you need to set the Content-Type headers to be "multipart/form-data", then as the second parameter in form-data use "categoryQueryDto" as key and add json as value ({'id': 'whatever'}).
After that change annotation for parameters from @RequestPart/@RequestBody to @RequestParam in your controller.
答案3
得分: 0
发布另一种我尝试过的解决方案,即将 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 = "文件上传成功:" + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
} catch (Exception e) {
message = "无法上传文件:" + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
}
}
message = "请上传 JSON 文件!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseMessage(message));
}
英文:
Posting another solution that I experimented with which was to append the id to the path for the call.
@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));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论