Pisałem niedawno małą aplikację webową na zlecenie. Aplikacja była oczywiście napisana w GWT :) Z rzeczy, których wcześniej nie pisałem aplikacja musiała korzystać z Hibernate i uploadwać pliki na serwer. No i z czym miałem najwięcej problemów ? Właśnie z uploadem :( Hibernate okazał się bardzo fajnym narzędziem (ale o tym pewnie osobny wpis kiedyś będzie). Ok więc najpierw jak zrealizować fileupload w GWT, a potem co ja spartoliłem :)
Ok wiec najpierw przyjrzyjmy się części po stronie klienta. GWT dostarcza nam komponent FileUpload, który zajmie się czarą robotą przy uploadzie. Co jest istotne ? Żeby dało się coś przesłać na serwer musimy umieścić to w formularzu, (klasa FormPanel). Musimy nadać formularzowi odpowiednią akcję tj. podać url-pattern do servletu, który zajmie się odebraniem pliku i zapisaniem go na serwerze. Oczywiście do przesyłania pliku użyjemy metody POST :)
[java]
final FileUpload plik = new FileUpload();
final FormPanel form = new FormPanel();
form.setAction("fileupload");
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
form.setWidget(plik);
//Gdy chcemy wysłać formularz z plikiem(np po kliknięciu na przycisk) wywołujemy:
form.submit();
[/java]
Jaki był mój błąd skoro cały ten upload jest taki prosty ? Najpierw zrobiłem sobie GUI, nie było FormPanelu tylko w głównym panelu miałem dodany FileUpload. Podczas zmian zapomniałem usunąć this.add(plik), i w ten sposób FileUpload zamiast znajdować się w formularzu znajdował się w głównym panelu. Wyglądało tak jak trzeba - ale nie działało :) Kilka godzin myślałem co jest nie tak.
Ok. Jak wygląda servlet odbierający nasz plik? Skoro przesyłamy plik o trzeba w nim zaimplementować swoją metodę doPost(). A servlet wygląda tak:
[java]
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 3404817164861510193L;
@SuppressWarnings("unchecked")
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(req)) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(req);
for (FileItem item : items) {
if (item.isFormField()) continue;
String fileName = item.getName();
if (fileName != null) {
fileName = FilenameUtils. getName(fileName);
}
File uploadedFile = new File(getServletContext().getRealPath(getServletContext().getContextPath()), fileName);
if (uploadedFile.createNewFile()) {
item.write(uploadedFile);
resp.setStatus(HttpServletResponse.SC_CREATED);
resp.getWriter().print("The file was created successfully.");
resp.flushBuffer();
} else
throw new IOException("The file already exists in repository.");
}
} catch (Exception e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"An error occurred while creating the file : " + e.getMessage());
e.printStackTrace();
}
} else {
resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
"Request contents type is not supported by the servlet.");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
}
}
[/java]

24 listopada 2011 o 22:08
Ostatnio sam walczyłem z uploadem plików za pomocą GWT i trafiłem m.in. tutaj. W moim przypadku leciał POST do Servlet’a, ale nie było w nim pliku. Okazało się, że bardzo ważne jest, aby przycisk do wysyłania został umieszczony w FormPanel’u. Zawsze warto spojrzeć na aktualną wersję dokumentacji: http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/FileUpload.html