AngularJS调用SpringBoot上传图片至FTP时遇415错误求助
问题:上传文件到SpringBoot服务时出现415不支持的媒体类型错误?
我尝试选择文件并上传至FTP,使用AngularJS调用SpringBoot服务发送图片时出现415(不支持的媒体类型)错误。目前仅需获取文件名,请问我在调用POST请求时哪里出错了?
Angular控制器代码:
Controllers.controller('UploadCtrl', [ '$scope', '$http', function($scope, $http) { $scope.doUploadFile = function() { var file = $scope.uploadedFile; var url = "/ui/upload"; var data = new FormData(); data.append('uploadfile', file); var config = { transformRequest : angular.identity, transformResponse : angular.identity, headers : { 'Content-Type' : undefined } } $http.post(url, data, config).then(function(response) { $scope.uploadResult = response.data; }, function(response) { $scope.uploadResult = response.data; }); }; } ]);
Java服务控制器代码:
@POST @Path("/upload") @Consumes("multipart/form-data") public String upload(@RequestParam("uploadfile") MultipartFile file) throws Exception { try { return "You successfully uploaded - " + file.getOriginalFilename(); } catch (Exception e) { throw new Exception("FAIL! Maybe You had uploaded the file before or the file's size > 500KB"); } }
问题分析与解决办法
出现415错误主要是因为SpringBoot没法正确解析你的请求,咱们一步步来排查修复:
1. 注解混用导致请求解析失败
你现在的Java代码同时混用了JAX-RS的@Path、@Consumes注解和Spring MVC的@RequestParam注解,两套框架的注解冲突,Spring根本不知道该怎么处理这个请求,自然返回“不支持的媒体类型”。
修复方案:换成纯Spring MVC注解
把代码改成下面这样,完全用Spring的注解来声明控制器和请求映射:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController // 告诉Spring这是一个REST风格的控制器 public class UploadController { // 路径要和Angular里的请求url完全一致:/ui/upload @PostMapping("/ui/upload") public String upload(@RequestParam("uploadfile") MultipartFile file) throws Exception { try { return "You successfully uploaded - " + file.getOriginalFilename(); } catch (Exception e) { throw new Exception("FAIL! Maybe You had uploaded the file before or the file's size > 500KB"); } } }
这里要注意几个关键点:
- 用
@RestController替代原来的JAX-RS控制器声明,让Spring能识别并管理这个类; @PostMapping("/ui/upload")的路径必须和Angular代码里的url = "/ui/upload"完全匹配;- 去掉JAX-RS的
@Path和@Consumes,Spring MVC会自动处理multipart/form-data类型请求,只要@RequestParam的参数名和FormData里的key(uploadfile)一致即可。
2. 确认multipart依赖是否存在
还要确保你的SpringBoot项目里已经引入了文件上传的相关依赖,一般spring-boot-starter-web已经包含了该依赖,如果你用Maven,pom.xml里要有:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
3. Angular代码的小确认
你的Angular代码其实没什么大问题,不过可以再检查一下:
- 确保HTML里的文件输入框正确绑定了
uploadedFile,比如:<input type="file" ng-model="uploadedFile" />; headers: {'Content-Type': undefined}这个设置是对的,Angular会自动根据FormData生成带boundary的正确请求头,手动设置反而容易出错。
按照上面的步骤调整后,应该就能正常接收文件并返回文件名了。
内容的提问来源于stack exchange,提问作者Sohaib Jamal
相关产品推荐
相关产品推荐

