Как отправить файл на мой WebService на основе Spring Boot с клиента Angular 5? - PullRequest
0 голосов
/ 11 мая 2018

Я потратил много времени на решение своей проблемы, но безуспешно.

У меня есть клиент Angular 5, и я хочу отправить файл в мой веб-сервис SpringBoot, чтобы я мог справиться с этимфайл на стороне веб-службы.

Мой шаблон:

<div class="dropdown-content">
                        <label (click)="openDialog()">Upload from xls</label>
                        <label>Save to xls</label>
                        <label>Link 3</label>
                        <input type="file" class="inputFile" style="display:none" (change)="handleFileInput($event.target.files)">
</div>

Я хотел бы иметь возможность выбрать файл после нажатия на ярлык Загрузить с xls:

openDialog() {
    let myInputFile = <HTMLElement>document.querySelector('.inputFile');
    myInputFile.click();
  }

  //This method is called after choosing a file
  handleFileInput(files: FileList) {
    var file = this.fileToUpload = files.item(0);
    this.uploadFileService.pushFileToStorage(file);
  }

Затем мы вызываем this.uploadFileService.pushFileToStorage (file);

@Injectable()
export class UploadFileService {

    constructor(private http: Http, private globals: Globals, private httpClient: HttpClient) { }

    pushFileToStorage(file) {

    let headers = new Headers();
    let options = new RequestOptions({ headers: headers }); // Create header

    let formData = new FormData();
    formData.append('file', file); // Append file to formdata
    console.log(file);

    const req = this.httpClient.post('http://localhost:' + this.globals.tomcatPort + '/utils/saveFromFile', JSON.stringify(formData));

    req.subscribe((data) => {

        console.log(data); // Sucess response
    }, (err: HttpErrorResponse) => {

        // Erro response
        if (err.error instanceof Error) {
            //client side error
            console.log('An error occured: ', err.error.message);
        }
        else {
            console.log('Backend returned code', err.status, 'body was ', err.error);
        }
    })

На стороне WebService мой StorageController выглядит (временно, для тестов)

    @RestController
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
@RequestMapping("/utils")
public class StorageController {

    @PostMapping(value = "/saveFromFile", consumes = "multipart/form-data", produces = MediaType.APPLICATION_JSON_VALUE)
    public void saveFromFile(@RequestParam("file") MultipartFile multipartFile) {
        System.out.println(multipartFile);
    }

    @Bean
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver multipart = new CommonsMultipartResolver();
        multipart.setMaxUploadSize(3 * 1024 * 1024);
        return multipart;
    }

    @Bean
    @Order(0)
    public MultipartFilter multipartFilter() {
        MultipartFilter multipartFilter = new MultipartFilter();
        multipartFilter.setMultipartResolverBeanName("multipartReso‌​lver");
        return multipartFilter;
    }
}

В настоящее времяЯ получаю сообщение об ошибке:

Не удалось загрузить http://localhost:8180/utils/saveFromFile: Ответ на предпечатный запрос не проходит проверку контроля доступа: заголовок «Access-Control-Allow-Origin» отсутствует назапрашиваемый ресурс.Origin 'http://localhost:4200' поэтому не разрешен доступ.Ответ имеет HTTP-код состояния 403.

У меня проблема с CORS, только когда я пытаюсь отправить файл.

Заранее спасибо!Матеуш

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Хорошо, наконец-то я решил свою проблему очень просто:

Угловой шаблон:

<div class="dropdown-content">
                        <label (click)="openDialog()">Upload from xls</label>
                        <label>Save to xls</label>
                        <label>Link 3</label>
                        <input type="file" class="inputFile" style="display:none" (change)="handleFileInput($event)">
                    </div>

Угловая составляющая:

openDialog() {
    let myInputFile = <HTMLElement>document.querySelector('.inputFile');
    myInputFile.click();
  }

  //This method is called after choosing a file
  handleFileInput(event) {
    var file = this.fileToUpload = <File>event.target.files[0];
    this.uploadFileService.pushFileToStorage(file);
  }

Угловое обслуживание:

pushFileToStorage(file) {
        const fd = new FormData();
        fd.append('file', file, file.name);
        this.httpClient.post('http://localhost:' + this.globals.tomcatPort + '/utils/saveFromFile', fd)
            .subscribe(res => {
                this.dataStorageService.getDictionaryItems();
            })
    }

и в WebService в моем контроллере:

@PostMapping(value = "/saveFromFile", consumes = "multipart/form-data", produces = MediaType.APPLICATION_JSON_VALUE)
    public void saveFromFile(@RequestParam("file") MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        convFile.createNewFile();
        FileOutputStream fos = new FileOutputStream(convFile);
        fos.write(file.getBytes());
        fos.close();

        storageService.saveWordsFromFile(convFile);

    }

И это все. Это работает!

0 голосов
/ 11 мая 2018

В UploadFileService вам нужно импортировать

import {HttpClient, HttpHeaders} from '@angular/common/http'

И при вызове службы POST вы можете сделать так, как если вы хотите установить заголовок Authorization с некоторым токеном, тогда этоспособ установить заголовок в целом.И снова, если вы хотите добавить больше, просто добавьте их

 const req = this.httpClient.post('http://localhost:' + 
 this.globals.tomcatPort + '/utils/saveFromFile', JSON.stringify(formData), 
 {headers: new HttpHeaders().set('Authorization', 'Basic jfghghjbhjb')});

Если вы не хотите использовать встроенные заголовки, вы можете создать отдельный объект, как показано ниже

const headers = new HttpHeaders().set('Authorization', 'Basic jfghghjbhjb')

и вы можете использовать это

const req = this.httpClient.post('http://localhost:' + this.globals.tomcatPort + '/utils/saveFromFile', JSON.stringify(formData), {headers: headers});

...