AngularJS向Java POST接口传文件遇405错误,请求排查
问题:AngularJS上传文件到Java后端报405错误及请求作用域关闭异常
使用AngularJS向Java应用发送POST请求上传文件时,出现405(Method Not Allowed)错误。移除Java接口方法的参数后,接口可正常被调用,同时错误日志显示请求作用域已关闭。
AngularJS代码
var imgMetadata = {author: "a",title: "a",description: "a.",keywords: "a"}; console.log("imgMetadata"+imgMetadata); var fd = new FormData(); fd.append('fileMetadata', JSON.stringify(imgMetadata)); fd.append('file', upoadFileField[0].files[0]); console.log("Call http"); var REST_BASE_URL = PluginHelper.getPluginRestUrl("apponboarding"); var uploadurl = REST_BASE_URL+ "/iiq/uploadfile"; console.log("File upload url is "+uploadurl); $http.post(uploadurl, fd, { transformRequest: angular.identity, headers: { "X-XSRF-TOKEN": PluginHelper.getCsrfToken(), "Content-Type": undefined } }).then(function successCallback(response) { console.log("In success callback"); var status = response.status;if(status == "200") { var isValid = response.data; console.log("FIleupload function in java "+isValid); if(isValid == "filecopied"){ $scope.errorText = "filecopied :"; } else { $scope.errorText = "Issue in copying"; } } }, function errorCallback(response) { console.log("In error callback"); $scope.errorText = "Error in callback file function"; });
Java代码
@POST @Path("/iiq/uploadfile") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadFile(@RequestParam("file") MultipartFile file) { try{ log.error("file received."); return Response.status(Response.Status.OK).entity("filecopied").build(); } catch (Exception e){ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Cannot copy!!").build(); } }
详细错误信息
2024-10-21T12:03:08,357 ERROR http-nio-8080-exec-7 sailpoint.web.SailPointContextRequestFilter:74 - java.lang.IllegalStateException: Request scope has been already shut down.
javax.servlet.ServletException: java.lang.IllegalStateException: Request scope has been already shut down.
解决方案
1. 统一后端注解规范
你的Java代码混用了JAX-RS(@POST、@Path)和Spring MVC(@RequestParam)的注解,这会导致参数解析失败,触发405错误。根据你的技术栈选择对应规范:
若使用Spring MVC:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @PostMapping("/iiq/uploadfile") public Response uploadFile(@RequestPart("file") MultipartFile file, @RequestPart("fileMetadata") String fileMetadata) { try{ log.error("file received."); // 可选:将fileMetadata解析为实体类 // ObjectMapper mapper = new ObjectMapper(); // ImgMetadata metadata = mapper.readValue(fileMetadata, ImgMetadata.class); return Response.status(Response.Status.OK).entity("filecopied").build(); } catch (Exception e){ log.error("Upload failed", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Cannot copy!!").build(); } }
若使用JAX-RS(如Jersey):
import javax.ws.rs.FormParam; import org.glassfish.jersey.media.multipart.FormDataParam; @POST @Path("/iiq/uploadfile") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadFile(@FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileDisposition, @FormDataParam("fileMetadata") String fileMetadata) { try{ log.error("file received."); // 处理文件流 return Response.status(Response.Status.OK).entity("filecopied").build(); } catch (Exception e){ log.error("Upload failed", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Cannot copy!!").build(); } }
2. 排查请求作用域关闭问题
异常提示请求作用域已关闭,需从以下方向排查:
- 检查
SailPointContextRequestFilter的逻辑,确保它不会在请求未处理完成时关闭请求作用域; - 确认Spring的
MultipartResolver配置正确,能正常解析multipart请求,避免解析失败导致上下文异常; - 在异常捕获中添加详细日志,定位具体触发作用域关闭的环节。
3. 验证前端请求配置
前端Content-Type: undefined的配置是正确的,浏览器会自动生成带boundary的multipart/form-data头。额外确认:
X-XSRF-TOKEN是否正确获取并传递;- 请求URL是否与后端接口路径完全匹配;
- 表单数据中的
file字段名是否和后端注解中的参数名一致。
内容的提问来源于stack exchange,提问作者Aditya Bhatnagar
相关产品推荐
相关产品推荐

