远程调用文件上传踩坑指南
1. 生产端所报异常:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found] with root cause
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
2. 消费端所报异常
status 500 reading FileUploadOpenFeignClient#upload(MultipartFile)
3. 生产者代码
controller层代码
@RestController
@RequestMapping("/file")
@Api(value = "文件上传")
public class FileUploadController {
@Autowired
FileUploadService fileUploadService;
@PostMapping(value = "/upload")
public String upload(@RequestParam("file") MultipartFile file){
if(ObjectUtil.isNull(file)){
return "文件不存在";
}
System.out.println(file.getSize());
//获取文件的名称
String fileName = file.getOriginalFilename();
return fileUploadService.upload(file,fileName);
}
}
service层代码
@Service
public class FileUploadServiceImpl implements FileUploadService {
@Override
public String upload(MultipartFile multipartFile,String fileName) {
System.out.println("文件");
try {
String suffix = FileUtil.extName(fileName);
//扩展名
System.out.println(suffix);
String newFileName = StrUtil.replace(UUID.randomUUID() + "." + suffix, "-", "");
System.out.println(newFileName);
String fileUploadPath = "E://Image//"+newFileName;
System.out.println(fileUploadPath);
File file = new File(fileUploadPath);
multipartFile.transferTo(file);
return UrlMappingCommon.FILE_URL+newFileName;
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
}
文件路径映射
public class UrlMappingCommon {
public final static String FILE_URL = "http://localhost:8081/files/";
public final static String FILE_MAP = "/files/**";
}
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler(UrlMappingCommon.FILE_MAP)
.addResourceLocations("file:E://Image//");
}
}
生产端postman测试正常
4. 消费端代码(错误示例)
@FeignClient(value = "mytesy1")
public interface FileUploadOpenFeignClient {
@PostMapping(value = "/file/upload",
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
)
public String upload(@RequestParam("file") MultipartFile file);
}
@RestController
@RequestMapping("/consumer")
@Api(tags = "学生远程调用")
public class ConsumerController {
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file){
return feignClient.upload(file);
}
}
postman测试端调用出现问题
4. 消费端代码(正确示例)
@FeignClient(value = "mytesy1")
public interface FileUploadOpenFeignClient {
@PostMapping(value = "/file/upload",
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}
)
public String upload(@RequestPart("file") MultipartFile file);
}
@RestController
@RequestMapping("/consumer")
@Api(tags = "学生远程调用")
public class ConsumerController {
@PostMapping("/upload")
public String upload(@RequestPart("file") MultipartFile file){
return feignClient.upload(file);
}
}
总结:
1. 远程调用文件上传必须加@RequestPart注解才能正常调用,@RequestParam就会报500错误,具体博主也不知道为啥子(生产端不需要改,消费端需要改),有懂的大佬可以评论区交流一下。
2. 写openFeignClient的时候在@postmapping后面加上
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE