# mehrere Mail Attachments - JSP Struts



## clemson (27. Dez 2005)

Hallo!

Folgendes Problem: Ich möchte in meiner WebApplikation (Struts) die Möglichkeit eines Email-Verkehrs zur Verfügung stellen. An die Emails sollen unbegrenzt viele Anhänge angehängt werden können.

Die Mails und die Attachments sollen in einer Oracle-Datenbank gespeichert werden. Das Problem das ich aber jetzt habe ist folgendes: wie schaffe ich es, dass mir auf der Seite, auf welcher die Email-Daten (An, Betreff, Inhalt) angezeigt werden, die Möglichkeit geboten wird, mehrere Datein als Anhang beizufügen...

Eine Datei hochzuladen (in der DynaActionForm hat diese den typ org.apache.struts.upload.FormFile) ist kein Problem - das Problem ist jetzt nur, wie ich es schaffe, dass nach einem hochladen einer Datei eine weitere Datei hochgeladen werden kann - ohne, dass die vorherigen Dateien gelöscht werden...

Ich habe mir folgenden Lösungsvorschlag überlegt: Die DynaActionForm besitzt ein property "file" vom typ org.apache.struts.upload.FormFile, und ein weiteres property "files" vom typ org.apache.struts.upload.FormFile[]. jedes mal, wenn eine neue datei hochgeladen wird, so wird diese  dem array hinzugefügt. beim abschicken werden dann alle FormFiles aus dem Array an die Mail angehängt...

Liege ich da mit meinem Ansatz richtig oder würdet ihr das anders lösen bzw. wie habt ihr das gelöst?


----------



## hugo (3. Jan 2006)

Vielleicht hilft bei deinem Beispiel das abkupfern bei GMX. Die regeln das so, dass immer nur eine Datei hochgeladen werden kann. Nachdem die Datei auf dem Server (wahrscheinlich in einer Tempvariablen o.ä.) liegt, kann man wieder eine Datei hochladen, solange bis man keinen Bock mehr hat. Die Dateien werden dann als hidden-fields o.ä. im Formular hinterlegt, so dass beim Versand alle Dateien mit rausgehen.

Gesundes neues hugo


----------



## clemson (3. Jan 2006)

hallo!

das habe ich mir auch schon so gedacht. aber das problem das ich jetzt dabei habe, ist das mit dem hidden-field...

ich habe in meiner struts-config.xml folgende definition für die actionform:

```
<form-bean name="mailwriteform" 
	type="org.apache.struts.action.DynaActionForm">
	<form-property name="file" type="org.apache.struts.upload.FormFile" />
</form-bean>
```

meine jsp seite sieht folgendermaßen aus (der interessante teil):

```
<tr>
	<td>
		<html:file size="80" property="file" />
	</td>
</tr>
<tr>
	<td>
		<html:submit property="action" value="file_upload" />
	</td>
</tr>
<html:submit />
```

wird der file_upload button gedrückt, so wird das file hinaufgeladen. wird der allgemeine submit button gedrückt, so soll das mail abgeschickt werden.

das problem das ich jetzt habe ist folgendes: wie mache ich das mit dem, dass das file gespeichert wird (mit dem hidden wie du als vorschlag gepostet hast...) denn im html formular kann man im prinzip ja nur strings abspeichern (über das hidden field), oder?

ich müsste also irgendwie eine möglichkeit haben, direkt auf die FormBean zugreifen zu können...

oder liege ich da auf dem holzweg?


----------



## Guest (3. Jan 2006)

Da du die Attachments ja eh in einer DB speichern möchtest, würde ich das einfach nach jedem hochladen einer Datei machen. Eine Referenz (id) des Datensatzes kannst Du dann ja in der Session speichern.
beim eigentlichen Versand müssen die entsprechenden Datensätze halt wieder ausgelesen werden.
Die Dateien im Speicher zu behalten, halte ich für nicht so empfehlenswert, zumal Du ja auch unbegrenzt viele Attachments zulassen möchtest.
(und in einem hiddenfield schon garnicht, da die Daten dann bei jedem neuen upload wieder mitgesendet werden müßten)

cu 
mark


----------



## clemson (3. Jan 2006)

hmm...

das problem ist jetzt nur (wenn ich die attachments gleich in die db schreibe), dass - falls der benutzer die mail-schreibe-aktion abbricht - ich mir überlegen muss, wie ich die "überflüssigen" attachments rausbekomm.

wegen der schnelligkeit, das wäre zu zeit nicht so das problem... weiß den jemand, wie das bei gmx gemacht wird?


----------



## clemson (3. Jan 2006)

eine frage die sich in diesem zusammenhang stellt: wie ist es denn grundsätzlich möglich, ein objekt - welches in einer jsp seite erstellt wird bzw. bereits in der jsp seite zur verfügung steht - wieder in eine formbean zu schreiben? bzw. dieses objekt einer anderen action zu übergeben?


----------



## mlange8801 (4. Jan 2006)

> das problem ist jetzt nur (wenn ich die attachments gleich in die db schreibe), dass - falls der benutzer die mail-schreibe-aktion abbricht - ich mir überlegen muss, wie ich die "überflüssigen" attachments rausbekomm.


Kannst ja auch erstmal nur temporär im Dateisystem speichern und dann beim eigentlichen Versand aus dem Dateisystem in die DB kopieren.

Hier mal eine modifizierte Uploadaction aus den Struts-examples:


```
public class UploadAction extends Action {
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		if (form instanceof UploadForm) {

			//this line is here for when the input page is upload-utf8.jsp,
			//it sets the correct character encoding for the response
			String encoding = request.getCharacterEncoding();
			if ((encoding != null) && (encoding.equalsIgnoreCase("utf-8"))) {
				response.setContentType("text/html; charset=utf-8");
			}

			String path = servlet.getServletContext().getRealPath("/")
					+ "uploads/";

			UploadForm theForm = (UploadForm) form;

			//retrieve the text data
			String text = theForm.getTheText();

			//retrieve the query string value
			String queryValue = theForm.getQueryParam();

			//retrieve the file representation
			FormFile file = theForm.getTheFile();

			//retrieve the file name
			String fileName = file.getFileName();

			//retrieve the content type
			String contentType = file.getContentType();


			//retrieve the file size
			String size = (file.getFileSize() + " bytes");

			String data = null;

			//Die Formfile Temporär im Dateisystem speichern
			boolean saved = saveFile(file.getInputStream(), path, request
					.getSession().getId()
					+ file.getFileName());
			if (saved) {
				ArrayList attachments = (ArrayList) request.getSession()
						.getAttribute("attachments");
				if (attachments == null) {
					attachments = new ArrayList();
				}

				attachments.add(request.getSession().getId()
						+ file.getFileName());

				request.getSession().setAttribute("attachments", attachments);
			}

		

			//destroy the temporary file created
			file.destroy();

			//return a forward to display.jsp
			return mapping.findForward("display");
		}

		//this shouldn't happen in this example
		return null;
	}

	public static boolean saveFile(InputStream in, String path, String file)
			throws IOException {

		//Diese Funktion könnte natürlich auch alternativ einen Blob in einer
		// DB speichern

		boolean success = false;
		OutputStream out = null;
		try {
			out = new BufferedOutputStream(new FileOutputStream(path + file));
			byte[] buffer = new byte[512];
			while (in.read(buffer) != -1) {
				out.write(buffer);
			}
			success = true;
		} finally {
			if (out != null)
				out.close();
			if (in != null)
				in.close();
		}
		return success;
	}
}
```

Und in der Versende Aktion dann sowas:

```
String path = servlet.getServletContext().getRealPath("/")
					+ "uploads/";
			//Dann später beim Versenden die Attachments wieder auslesen.

			ArrayList attachments = (ArrayList) request.getSession()
					.getAttribute("attachments");

			org.apache.commons.mail.MultiPartEmail email = new MultiPartEmail();
			email.setDebug(true);
			for (int i = 0; i < attachments.size(); i++) {
				org.apache.commons.mail.EmailAttachment attachment = new EmailAttachment();
				attachment.setPath(path + attachments.get(i));
				attachment.setDisposition(EmailAttachment.ATTACHMENT);
				attachment.setName(attachments.get(i).toString().replaceFirst(
						request.getSession().getId(), ""));
				email.attach(attachment);
			}
			email.setAuthentication("smtpusername", "smtppass");
			email.setHostName("smtphost");

			email.addTo("email@wasauchimmer.de", "Vorname Name");
			email.setFrom("mir@test.de");
			email.setSubject("uploadtest");
			email.setMsg("blabla");
			email.send();
//Jetzt vielleicht noch die Dateien aus dem Dateisystem in die DB transferieren.
//Und vielleicht Täglich die Dateien aus dem Dateisystem löschen.
```

cu
mark


----------



## clemson (4. Jan 2006)

hey cool, danke für deine bemühungen! ich werd das gleich mal auspobieren!

vielen dank!!


----------

