使用 Angular2 将 MultipartFile 作为请求参数发送到 REST 服务器

Posted

技术标签:

【中文标题】使用 Angular2 将 MultipartFile 作为请求参数发送到 REST 服务器【英文标题】:Sending a MultipartFile as a Request Param to REST server using Angular2 【发布时间】:2017-10-23 02:02:44 【问题描述】:

我需要上传一张使用 Spring Boot 编写的照片到服务器。对于发送请求的前端,我使用 Angular2。

这是我接受 HTTP 请求的 API。它工作正常。 (我用 Postman 测试过)

@RequestMapping(method = RequestMethod.POST, value = "/tender/save-new/save-photo")
public ResponseEntity<?> uploadPhoto(@RequestParam("file") MultipartFile file)

    if (file.isEmpty()) 
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage("DEBUG: Attached file is empty");
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
    
    String returnPath = null;
    try 
        // upload stuff
     catch (IOException e) 
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage(e.getMessage());
        return new ResponseEntity<ErrorResponse> (errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    

    return new ResponseEntity<String>(returnPath, HttpStatus.OK);

我不确定我应该如何在 Angular2 中编写代码来调用服务器。 以下是我想出的。

 savePhoto(photoToSave: File) 

    let formData: FormData = new FormData();
    formData.append('file', photoToSave);

    let savedPath = this._http
        .post(this._endpointUrl + "tender/save-new/save-photo", formData)
        .map(
        res => 
            return res.json();
        
        )
        .catch(handleError);

    return savedPath;

如您所见,我在发送表单数据之前将'file' 参数附加到表单数据中。服务器方法接受RequestParam 作为'file'

但是,在服务器日志中,我收到以下错误。

org.springframework.web.multipart.MultipartException:当前请求 不是多部分请求 org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:190)

请注意,我没有声明 CommonsMultipartResolver bean,因为 SprinBoot 隐式处理它。 (我听说过。如果我错了,请纠正。)

我认为错误是由于请求中缺少值而出现的。 handleMissingValue 的 Spring 在说什么?我错过了什么?

【问题讨论】:

【参考方案1】:

您需要指定您的控制器需要多部分

@RequestMapping(method = RequestMethod.POST, value = "/tender/save-new/save-photo", consumes = "multipart/form-data")
public ResponseEntity<?> uploadPhoto(@RequestParam("file") MultipartFile file)

还要解决 CORS 问题,您需要添加您计划在 cors 映射中使用的方法,尝试类似这样的方法

 @Configuration
 public class WebMvcConfiguration 

@Bean
public WebMvcConfigurer corsConfigurer() 
    return new WebMvcConfigurerAdapter() 
        @Override
        public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
        
    ;


【讨论】:

但是根据下面的回答,Angular2 final 支持不带xhr的文件上传***.com/a/39862337/3892439 嗯,这很有趣,不知道它是否受支持,您是否在解决方案的第二部分中将 consumes = "multipart/form-data" 放入请求映射中? 是的。现在它给了我``请求的资源上不存在'Access-Control-Allow-Origin'标头。因此,Origin 'localhost:3000' 不允许访问。 ` .但问题是我已将@CrossOrigin(origins = "http://localhost:3000") 放入我的控制器中 好的,那么你的问题就解决了,这个错误与 CORS 协议有关,它保护你的控制器不被其他域访问,我也会编辑我的答案来解决这个问题。 如果它解决了您的问题,请随时接受答案【参考方案2】:

我遇到了同样的问题,这是我现在使用的解决方案:

对于使用spring boot的后端:

 @RequestMapping(value="/save", method = RequestMethod.POST)
public ResponseEntity<?> saveTemp(@RequestParam("file") MultipartFile file) throws Exception
    String nomFichier=file.getOriginalFilename();

    try 
        byte[] bytes = file.getBytes();
        File fi=new File(tempRepo+nomFichier);
        fi.getParentFile().mkdirs();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream((new FileOutputStream(fi)));
        bufferedOutputStream.write(bytes);
        bufferedOutputStream.close();



     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    
    return new ResponseEntity<>(HttpStatus.OK);

对于使用Angular2的前端:

public save(file:any)

 const formData = new FormData();
 formData.append("file", file);

 return this._http
  .post('http://localhost:8081/save', formData)
  .catch(this._errorhandler);

【讨论】:

你是否将特定http请求的标头设置为某些东西? 不,我没有设置请求的头部,它是自动完成的

以上是关于使用 Angular2 将 MultipartFile 作为请求参数发送到 REST 服务器的主要内容,如果未能解决你的问题,请参考以下文章

使用 Angular2 将文件上传到 REST API

如何将 ExpressJS 服务器与 Angular2 集成

Angular2 - 将 div 添加到 DOM

使用Angular2中的接口将对象推送到新数组中

使用 Angular2 将 MultipartFile 作为请求参数发送到 REST 服务器

使用 NodeJS 将 Angular2 项目连接到 SpringBoot (Java) 的最佳实践