【问题标题】:Spring and Angular2 400 (Bad Request)Spring 和 Angular2 400(错误请求)
【发布时间】:2016-12-01 04:00:20
【问题描述】:

我在上传文件到 Spring 时收到 400(错误请求)。

上传在邮递员上工作正常,但在 Angular2 上不太好。

这是邮递员代码。工作得很好。。 我使用了基本身份验证和用户名 + 密码

var data = new FormData();
data.append("uploadfile", "pasta2.zip");

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
 if (this.readyState === 4) {
console.log(this.responseText);
  }
 });

xhr.open("POST", "http://localhost:8080/api/uploadFile");
xhr.setRequestHeader("authorization", "Basic b3BlcmF0aW9uczpvcGVyYXRpb25z");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("postman-token", "59d5ebf2-6039-e924-1550-c96e491f97ee");

xhr.send(data);

这是我的 Spring 控制器。它很简单地获取文件并将其保存到磁盘。

@RestController
public class uploadFile {

private Logger logger = LoggerFactory.getLogger(this.getClass());
public String filenameZip, directoryZip;


@RequestMapping(value = "/api/uploadFile", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> uploadFile(
        @ModelAttribute("uploadfile") MultipartFile uploadfile) {




    try {
        // Get the filename and build the local file path (be sure that the
        // application have write permissions on such directory)
        String filename = uploadfile.getOriginalFilename();
        String directory = "C://Develop//files";
        String filepath = Paths.get(directory, filename).toString();

        filenameZip = "c:/Develop/files/"+filename;
        directoryZip = "c:/Develop/files";

        // Save the file locally
        BufferedOutputStream stream =
                new BufferedOutputStream(new FileOutputStream(new File(filepath)));
        stream.write(uploadfile.getBytes());
        stream.close();

    } catch (Exception e) {
        System.out.println(e.getMessage());
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }
        unzip(filenameZip, directoryZip);
        return new ResponseEntity<>(HttpStatus.OK);
} // method uploadFile

这是我的 Angular2: 上面是更多代码。如果你需要,我可以提供。

/**
 * File upload
 * Upload a Zip file to server. 
 */

 filesToUpload: Array<File>;


/**
 * FormData gets the file as an Object and Post it on xhr with Auth
 * Upload a Zip file to server. 
 */

upload() {
    this.makeFileRequest("http://localhost:8080/api/uploadFile", [], this.filesToUpload).then((result) => {
        console.log(result);
    }, (error) => {
        console.error(error);
    });
}

fileChangeEvent(fileInput: any){
    this.filesToUpload = <Array<File>> fileInput.target.files;
}


makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
    return new Promise((resolve, reject) => {
        var formData: any = new FormData();
        var xhr = new XMLHttpRequest();
        for(var i = 0; i < files.length; i++) {
            formData.append("uploads[]", files[i], files[i].name);
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    resolve(JSON.parse(xhr.response));
                } else {
                    reject(xhr.response);
                }
            }
        }
        xhr.open("POST", url, true);


        /**
        * Must set the Authorization or the Spring MVC does not accept the request. Tested on Postman
        */
        xhr.setRequestHeader('Authorization', 'Basic ' + btoa("operations" + ":" + "operations"));

        xhr.withCredentials = true; 
        xhr.send(formData); //Form data is sent to Spring
    });
}

当我从我的应用上传文件时来自春天的日志:

2016-11-27 19:14:57.862  INFO 3596 --- [io-8080-exec-10] o.e.ws.service.AccountServiceBean        : > findByUsername
2016-11-27 19:14:57.875  INFO 3596 --- [io-8080-exec-10] o.e.ws.service.AccountServiceBean        : < findByUsername
2016-11-27 19:14:57.986  INFO 3596 --- [io-8080-exec-10] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Sun Nov 27         
19:14:57 UTC 2016, principal=operations, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null}]
null

我使用 Postman 应用时 Spring 的日志:

2016-11-27 19:16:12.762  INFO 3596 --- [nio-8080-exec-1] o.e.ws.service.AccountServiceBean        : > findByUsername
2016-11-27 19:16:12.851  INFO 3596 --- [nio-8080-exec-1] o.e.ws.service.AccountServiceBean        : < findByUsername
2016-11-27 19:16:12.965  INFO 3596 --- [nio-8080-exec-1] o.s.b.a.audit.listener.AuditListener     : AuditEvent [timestamp=Sun Nov 27     
19:16:12 UTC 2016, principal=operations, type=AUTHENTICATION_SUCCESS, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null}]
Unzipping to c:\Develop\files\pasta2\dsa.txt

在 Chrome 上显示:

zone.js:1382 POST http://localhost:8080/api/uploadFile 400 (Bad Request)

我相信这不是随请求一起发送 zip 文件。

【问题讨论】:

  • 邮递员日志是怎么说的?
  • 对不起。邮递员日志是什么意思?
  • “这是邮递员代码。工作正常” 此代码不上传文件。此外,在您的 Spring 代码中,@ModelAttribute("uploadfile") 应该是 @RequestParam("uploadfile")。您的 Angular 代码使用 uploads[] 而不是 uploadFiles。选择一个。

标签: java spring spring-mvc angular


【解决方案1】:

由于您可以通过 Postman 完成您想要的,我可以放心地假设您的问题不在后端。 问题是您没有在请求中附加任何 Multipart 文件,在前端(代码的 Angular 部分)。

操作 XHR 请求是一种粗略的方式来做到这一点,自从 Angular 的最终版本以来,你不需要这样做。

这样做的一个好方法是创建一个专门的服务来执行文件上传:

import { Injectable } from '@angular/core';

import {Http, Headers, Response} from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class UploadService {

    //Import your APIs endpoint
    private url = AppSettings.API_ENDPOINT;

    constructor(private http:Http) { }

    upload(files:FileList){

        var formData = new FormData();


        if(files.length > 0){

            for(var i = 0; i < files.length; i++){
                formData.append("uploadfile", files[i]);
            }
            return this.http
                .post(this.url + '/api/upload', formData)
        }

    }
}

然后在你的组件中订阅服务

uploadDocs($event:any){
    console.log("IMPORT")

    var files:any = $event.target.files;
    console.log(files);

    this.uploadService.uploadLibraries(files)
            .subscribe(data => this.successImport(data),
            error => this.failImport(error));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 2014-12-31
    相关资源
    最近更新 更多