Angular - upload plików

0

Witam wszystkich,
Chciałbym Was serdecznie poprosić o pomoc. Chcę napisać w angularze usługę która pobierze mi dane z formularza wraz z danymi tam wpisanymi i wyśle całość wraz z plikiem na serwer. Wysyłka wygląda tak że robię strzał poprzez https (mam url) do servletu napisanego w Javie, servlet przyjmuje dane w formacie json (nazwa, wartość). Mam stworzony formularz:

	<form method="post" enctype="multipart/form-data" accept-charset="UTF-8" id="insertDocumentListForm">
		<table>
			<tbody>				
				<tr>
					<td>typ: </td><td><input name="documentType" value="typ" type="text"></td>
				</tr>
				
				<tr>
					<td>idUzytkownika: </td><td><input name="insertedDocument.userId" value="000" type="text"></td>
				</tr>
				<tr>
					<td>nazawaDokumentu: </td><td><input name="insertedDocument.documentName" value="test2" type="text"></td>
				</tr>

				<tr>
					<td>file: </td><td><input name="file1" size="60" type="file"></td>
				</tr>
				<tr>
					<td>file: </td><td><input name="file2" size="60" type="file"></td>
				</tr>
				<tr>
					<td>maxAttachmentNumber: </td><td><input name="maxAttachmentNumber" value="3" type="text"></td>
				</tr>

			</tbody>
		</table>	
		
		<input name="sendResponse" value="true" type="hidden">
		<input name="uploaderPlugin" value="IFrame" type="hidden">
		<input name="env" value="TST" type="hidden"><br> 
		<input value="Upload" type="submit">
		
	</form>

I teraz potrzebuję pobrać te dane z formularza i w formacie json wraz z plikiem wysłać do tego servletu który wrzuci plik na serwer. Kod w angularze mam taki:

<script type="text/javascript" src="js/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);

function myFunction($scope, $http) {
	$scope.uploadFile = function() {
		http({
			method: 'POST',
			url: 'tu_wpisany_jest_adres_https_servletu',
			headers: {'Content-Type': "application/json"},
			data: insertDocumentListForm,
			transformRequest: function(data, headerGetterFunction) {
				return data;
			}
		}).success(function(data, status) {
		})
		  .error(function(data, status) {
		});
	};	
};
</script>

Oczywiście ona nie działa niestety ponieważ próbowałem ją napisać na wzór podobnej znalezionej w sieci, niestety tam brakowało kodu formularza i zapewne gdzieś coś źle się odwołuję. Generalnie błędów żadnych nie mam, ona zwyczajnie nie działa. Nie chcę Was prosić o gotowca żeby ktoś napisał to za mnie, zależy mi jedynie na wskazaniu gdzie robię błąd i w jaki sposób pobrać dane z formularza wraz z plikiem, przerobić to na JSON-a i przekazać do servletu.
0

A dlaczego chcesz wysyłać plik w JSONie i jak wyglada API po stronie serwera?

0

Bardzo dziękuję za odpowiedź. JSON-a wysyłam z tego względu że servlet który jest napisany w Javie, przyjmuje właśnie taki format, żadnego innego. Dlatego też muszę w skrypcie pobrać dane z formatki wypełnione przez użytkownika (dane są wymagane, wymaga ich servlet) następnie pobrać załączony plik i w formacie JSON wysłać coś takiego do servletu (mam podany adres HTTPS dla metody insert) który dalej odpala wemservice i ładuje całość do bazy. Na to wpływu nie mam ponieważ gdyby tak było to napisałem bym swój własny servlet w javie tak aby to grała ale cóż, to ja muszę się dostosować do tego co już jest zrobione.

0

Nie wyślesz pliku w jsonie. Jedynie możesz spróbować zakodować plik w base64 i przesłać w takim formacie a potem rozkodować po stronie serwera.

0

Spróbuj wysłać ten request z headers: { 'Content-Type': undefined } zamiast headers: {'Content-Type': "application/json"}.
Jeśli to nie pomoże, pokaz jak budujesz ten insertDocumentListForm.

0

Przerobiłem swój plik żeby to miało trochę większy sens. Póki co próbuję wysłać do servletu sam komunikat w postaci treści, bez żadnego pliku. Coś już się dzieje ale bo próbuje cokolwiek zrobić i jest jakaś reakcja w Firebugu bo wcześniej nie było kompletnie nic. Na chwilę obecną tak wygląda mój plik html gdzie buduję formularz:

<!DOCTYPE html>
<html data-ng-app = "myApp">
<head>
    <meta charset = "UTF-8">
    <title>Test</title>
    <script src = "Biblioteki/Angular/angular.min.js"></script>
    <script src = "Skrypty/skrypt.js"></script>
</head>

 

<body data-ng-controller = "FormController">
    <h1>Wprowadź dane: </h1>
    <ul>
        <li data-ng-repeat="Komunikat: ">{{message}}</li>
    </ul>
    <div>
        <label>documentType:</label>
        <input data-ng-model="data.documentType" type="text">
    </div>
    <div>
        <label>sourceSystem:</label>
        <input data-ng-model="data.insertedDocument.sourceSystem" type="text">
    </div>
    <div>
        <label>userId:</label>
        <input data-ng-model="data.insertedDocument.userId" type="text">
    </div>
    <div>
        <label>documentName:</label>
        <input data-ng-model="data.insertedDocument.documentName" type="text">
    </div>
    <div>
        <input data-ng-click="submit()" type="button" value="Wyślij">
    </div> 
</body>            
</html>

Tak wygląda mój pliczek js:

var formApp = angular.module('myApp', []);
formApp.controller('FormController', [
    '$scope', '$window', '$http',
    function ($scope, $widnow, $http) {
        $scope.messages = [];
        $scope.data = {};
        $scope.submit = function() {
            $http({
                method: 'POST',
                url: 'https://link_do_uslugi',
                data: $scope.data
            }).
            success(function(data, status, headers, config) {
                $widnow.location.replace('./confirm.html');
            }).
            error(function(data, status, headers, config) {
                alert('Błąd!')   
            });
        };
    }]);

Po wywołaniu tego poprzez wciśnięcie przycisku wyślij generuje się alert z błędem. Poniżej screen z konsoli:

Nie wiem czy problemem może być to że w angularze korzystam z $http natomiast link do servletu jest w https? Ogólnie sam komunikat w JSON-ie tworzy się prawidłowo, pobiera sobie wpisane wartości z formularza natomiast jak widać nagle usługa zostaje przerwana i nie można nic zrobić.

0

czy problemem może być to że w angularze korzystam z $http natomiast link do servletu jest w https?

$http jest serwisem do obsługi requestów, więc nie ma wpływu na protokół po jakim wysyłasz dane. HTTPS sam wskazujesz w url.

Jaki dostajesz kod odpowiedzi w headerze?

0

Tak to wygląda w FF:

Dodatkowo w konsoli mam jeszcze taki błąd:
Error: [$rootScope:inprog] http://errors.angularjs.org/1.5.9/$rootScope/inprog?p0=%24digest

Po stronie IE wszystko śmiga, inserty przechodzą, nie ma żadnych błędów :)

---EDIT---
A nie, za szybko się pochwaliłem. W IE działa ale losowo, nie wiem od czego to zależy. Na początku nie działało, później zaczęło działać a teraz znowu nie działa i zwraca błąd: SCRIPT7002: XMLHttpRequest: Błąd sieciowy 0x2ee4, Nie można zakończyć operacji z powodu błędu 00002ee4.

0

Nie widzę, żebyś miał ustawione Content-Type: multipart/form-data

0
mr_jaro napisał(a):

Nie widzę, żebyś miał ustawione Content-Type: multipart/form-data

Rozumiem że chodzi dokładnie o coś takiego:

...
$http({
                method: 'POST',
                url: 'https://10.2.96.44:9443/bpmproxy/ecms/insertDocumentList.ecms',
                headers: {
                    'Content-Type':'multipart/form-data'
                },
                data: $scope.data
            }).
...

Jeżeli tak to niestety to nie pomogło. Komunikaty przechodzą ale w odpowiedzi zwrotnej otrzymuję:

 
{"docId":null,"status":"ERROR","errorDetails":"DETAILS NOT AVAILABLE. SEE SYSTEM LOG FILE","errorCode":null}

Źle też buduje sam komunikat który wygląda tak:

 
{"documentType":"dfg","insertedDocument":{"sourceSystem":"dfg","userId":"dfg","documentName":"dfg","attribute0":{"file_name":"dfg"}},"maxAttachmentNumber":"3"}

Brakuje w tym komunikacie samego pliku.

0

Od poczatku:

servlet przyjmuje dane w formacie json (nazwa, wartość)

Jeśli wysyłasz same dane, bez pliku, wyślij je w takim requescie:

$http({
                method: 'POST',
                url: 'https://10.2.96.44:9443/bpmproxy/ecms/insertDocumentList.ecms',
                headers: {
                    'Content-Type':'application/json'
                },
                data: $scope.data
            })

Jesli chcesz do tego dolozyc do tego plik, bedziesz musial zmienic Content-Type, jesli serwer nie akceptuje 'multipart/form-data' sprobuj go oszukac z 'Content-Type':'undefined'

0

Ok, już trochę jaśniej. Content-type muszę dodać w pliku js czy w samym html-u? Serwer obsłuchuje Content-Type: application/form-data :)

0
kingu80 napisał(a):

Ok, już trochę jaśniej. Content-type muszę dodać w pliku js czy w samym html-u? Serwer obsłuchuje Content-Type: application/form-data :)

Jeśli tylko to obsługuje to nie wyślesz pliku tyle w temacie.

0

Plik wyślę ponieważ zwykła najprostsza formatka zbudowana w html-u jak najbardziej sobie z tym radzi, generuje prawidłowego POST-a i w odpowiedzi zwraca ID pliku. Problem jest tylko gdy próbuję zrobić to w angularze.

0

Serwer obsłuchuje Content-Type: application/form-data

Ale mieszasz :)

Wtedy wyslasz dane tak jak wspomnial @mr_jaro, tylko upewnij sie ze sa w odpowiednim formacie. Request wtedy bedzie wygladal:

$http({
                method: 'POST',
                url: 'https://10.2.96.44:9443/bpmproxy/ecms/insertDocumentList.ecms',
                headers: {
                    'Content-Type':'multipart/form-data'
                },
                data: $.param($scope.data)
            }).

Zwroc uwage na $.param($scope.data)

0

$ muszę gdzieś czymś zadeklarować? Bo dostaję komunikat że brak deklaracji $

1 użytkowników online, w tym zalogowanych: 0, gości: 1