【问题标题】:Sending a MultipartFile as a Request Param to REST server using Angular2使用 Angular2 将 MultipartFile 作为请求参数发送到 REST 服务器
【发布时间】: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 在说什么?我错过了什么?

【问题讨论】:

    标签: spring angular http spring-boot


    【解决方案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的文件上传stackoverflow.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请求的标头设置为某些东西?
    • 不,我没有设置请求的头部,它是自动完成的
    猜你喜欢
    • 2021-02-09
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多