Datei-Upload mit JQuery und Jersey

Infostudent

Grünschnabel
Hallo,

ich versuche schon seit mehreren Tagen einen einfachen Datei-Upload mit Jersey und Javascript/JQuery zu erstellen, aber bin bislang immer gescheitert.

Es geht darum, dass der User eine Textdatei auswählt (lokal auf seinem Rechner) und deren Inhalt gelesen und weiterverarbeitet wird. Das Lesen soll serverseitig geschehen, die ausgewählte Datei muss also an das Servlet übergeben werden.

Die Jersey-Klasse hat folgenden Aufbau, den ich grob aus Tutorials entnommen und für Testzwecke vereinfacht habe:


Code:
package de.objectmatching.service;

import java.io.InputStream;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.multipart.FormDataParam;


@Path( "/upload")
/**
 * Servlet to load the content of the text files and display it in the console. 
 * 
 */
public class ResourceUpload {
		
	
	@POST
	@Consumes( MediaType.MULTIPART_FORM_DATA)
	public void uploadFile( @FormDataParam("file") InputStream inputStreamReference) {
 
		System.out.println( "test");  

                // Read the file...
 
	}
	

}


Die uploadFile-Methode soll ein InputStream-Objekt bekommen, das dann mit einem InputStreamReader gelesen werden soll. Mein Problem ist momentan, dass ich nicht genau weiß, wie ich clientseitig ein InputStream-Objekt erzeuge, so dass ich das Servlet korrekt aufrufen kann. Wir haben uns geeinigt, JavaScript bzw. JQuery zu verwenden, daher sieht mein bisheriger Ansatz wie folgt aus:

HTML:
<html>    
	<head>
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
		
		<!-- Load JQuery Library -->
		<!-- =================== -->
		
		<script type="text/javascript"
			src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
		

		<!-- Handle Actions -->
		<!-- ============== -->
		
		<script type="text/javascript">    

			$(document).ready( function() {
				
				$("form").submit( function(e){
					
					var file = document.getElementById( 'ref').files[0];
	
	            			if( file.value.length == 0) {
	               				alert ("Please specify the path to the file to upload!");
	            			} else {
						

					// Call Servlet (pass file):	
							
					$.post( "http://127.0.0.1:8080/ObjectMatcher/upload", file);

					}
					
				});
					
			});

		</script>
		
    </head>
	
	
	<!-- Form Part -->
	
    <body>
    	<h1>Object Matching Evaluation</h1>
		<br />
		<i>Please select a reference alignment, source file and target file.</i>
		<br /><br /><br />
		<form method="post" enctype="multipart/form-data">
        <table border="0">
        	  <colgroup>
   				 <col width="200">
    				<col width="250">
    				<col width="200">
  				</colgroup>
            <tr>
            	<td><b>Reference Alignment:</b></td>
                <td><input id="ref" type="file"></td>
            </tr>
			<tr>
            	<td><b>Source File:</b></td>
                <td><input id="src" type="file" /></td>
            </tr>
			<tr>
            	<td><b>Target File:</b></td>
                <td><input id="trg" type="file" /></td>
            </tr>
        </table>

		<br />
		<button id="button">Submit</button>
		</form>

		<br/> 
    </body>

</html>


Die Servletmethode wird hierbei jedoch nicht ausgeführt. Weiß jemand, wie ich ein InputStream-Objekt erstelle, dass ich dann Jersey übergeben kann, so dass es funktioniert?

Ich habe auch in manchen Tutorials gesehen, dass überhaupt kein JS/JQuery verwendet wurde, sondern direkt aus dem Form heraus das Servlet aufgerufen wurde (action="..."). Allerdings gab es dabei bei mir immer einen 404-Fehler und funktioniert hat es ebenfalls nicht.

Ich verwende Apache Tomcat v.7.0 (Windows 64-bit), Java 1.6 und Jersey Version 1.12 (bundle + multipart). Zum Anzeigen verwende ich Firefox 13.0.1. Ich hab leider bisher noch keine Erfahrung mit Webservices, daher ist jede Hilfe sehr willkommen!

Vielen Dank im Voraus!
 
Hallo,

hier mal ein einfaches Beispiel zu einem File Upload mit JAX-RS (Jersey) über einen "hidden" IFrame.
Verwendet habe ich hier Jersey 1.12 unter Tomcat 7.0.27

Das Beispiel verwendet die Konfiguration unter:... als Ausgangsbasis.
http://www.tutorials.de/enterprise-...-webservice-mit-jersey-json-ueber-jquery.html

Ich musste noch die jersey Multipart Unterstützung zu den Maven Dependencies hinzufügen:
XML:
		<dependency>
			<groupId>com.sun.jersey.contribs</groupId>
			<artifactId>jersey-multipart</artifactId>
			<version>${jersey.version}</version>
		</dependency>

HTML:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JAX RS / File Upload Example</title>

</head>
<body>
	<form id="frm-upload" enctype="multipart/form-data" method="post" action="resources/uploads/upload" target="upload_target">
		<label for="new_file">Datei</label>:<input name="file" type="file"></input> <!-- you have to use the name attribute here, without it the file is not transfered****** -->
		<input type="submit" value="upload"></input>
	</form>
	<iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe> 
</body>
</html>

Unsere Upload JAX-RS Resource:
Java:
package de.tutorials.app.web.upload.remote;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

@Path("uploads")
public class UploadResource {

	@Context 
	private ServletContext servletContext;
	
	@POST
	@Path("/upload")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public Response upload(
				 @FormDataParam("file") InputStream fileContents
				,@FormDataParam("file") FormDataContentDisposition fileDetail
				) throws Exception {
		System.out.printf("Processing upload File: %s Size: %s bytes%n",fileDetail.getFileName(), fileDetail.getSize() == -1 ? fileDetail.getSize() : "unknown" );
		
		
		saveFile(fileContents, fileDetail, servletContext.getRealPath("upload"));
		
		return Response.ok(fileDetail.getFileName()).build();
	}

	private void saveFile(
				 InputStream fileContents
				,FormDataContentDisposition fileDetail
				,String absoluteTargetFolder) throws Exception{
		
		File targetFile = new File(absoluteTargetFolder,fileDetail.getFileName());		
		//TODO handle existing file
		OutputStream fos = new BufferedOutputStream(new FileOutputStream(targetFile));
		int b = -1;
		while((b = fileContents.read()) != -1){
			fos.write(b);
		}
		fos.close();
	}
}




Gruß Tom
 
Zuletzt bearbeitet von einem Moderator:
Danke Tom, jetzt funktioniert es!

Ich hab unser Projekt nicht als Maven-Projekt angelegt, aber ich habe gemerkt, dass bei mir die Library mimepull.jar gefehlt hat, die offensichtlich benötigt wird. Daher haben wohl auch die vorherigen Versuche nie geklappt.
 
Zurück