Nasıl dosyaları kullanarak JSP/Sunucu uygulaması sunucuya yüklemek için?
Nasıl kullanarak JSP/Sunucu uygulaması sunucuya dosya yükleyebilir miyim? Bunu denedim:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Ancak, ben sadece dosya adı, dosya içeriği değil. enctype="multipart/form-data"
eklediğimde <form>
, request.getParameter()
null
döndürür.
Araştırma sırasında Apache Common FileUpload sendeledi. Bunu denedim:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
Ne yazık ki, sunucu uygulaması açık bir mesaj ve bir neden olmadan bir istisna attı. Burada stacktrace:
SEVERE: Servlet.service() for servlet UploadServlet threw exception
javax.servlet.ServletException: Servlet execution threw an exception
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:637)
CEVAP
Giriş
Ve bir dosya seçin yükleme şeklinde <input type="file">
HTML bir alan gerekir. HTML specification belirtilen POST
yöntemi kullanmak zorunda ve form enctype
öznitelik 11* *için ayarlanmış olması gerekir.
<form action="upload" method="post" enctype="multipart/form-data">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Böyle bir formu gönderdikten sonra, ikili çoklu form verileri enctype
set olmadığı zaman daha a different format istek vücutta kullanılabilir.
3.0, Sunucu API Sunucu uygulaması önce doğal destek multipart/form-data
yoktu. Sadece varsayılan form application/x-www-form-urlencoded
şifre türü destekler. request.getParameter()
ve hanımları çok parçalı form verilerini kullanarak null
dönecekti. Bu iyi bilinen Apache Commons FileUpload devreye girdi.
Elle ayrıştırma yok!
Teoride ServletRequest#getInputStream()
kendine göre ayrıştırabilir. Ancak, bu RFC2388 kesin bilgi gerektiren hassas ve sıkıcı bir iştir. Bunu tek başına yapmak ya da bazı homegrown kütüphane-daha az kod internette başka bir yerde bulunan copypaste etmeye çalışmamalısınız. Birçok online kaynakları bu, roseindia.net gibi zor başarısız oldu. Ayrıca uploading of pdf file bkz. Kullanılan gerçek bir kütüphane (ve dolaylı olarak test!) kullanmalısınız yerine yıllardır milyonlarca kullanıcı tarafından. Böyle bir kütüphane sağlamlığı kanıtlanmıştır.
Zaten Sunucu uygulaması 3.0 veya daha yeni olunca, yerel API kullanın
Kullanıyorsanız en azından Sunucu uygulaması 3.0 (7 Tomcat, JBoss AS 6, Önemli olan 3, vs.), daha sonra sadece standart API sağlanan HttpServletRequest#getPart()
bitirirken tek parçalı form veri kalemleri (çoğu Sunucu uygulaması 3.0 uygulamaları aslında Apache Commons FileUpload yorganın altında bu!). Ayrıca, normal form alanları getParameter()
her zamanki gibi tarafından kullanılabilir.
İlk ve multipart/form-data
isteklerini tanımak ve destek getPart()
işe almak böylece izin için @MultipartConfig
ile sunucu uygulaması açıklama:
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
// ...
}
Daha sonra, aşağıdaki gibi: doPost()
uygulamak
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String description = request.getParameter("description"); // Retrieves <input type="text" name="description">
Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
String fileName = filePart.getSubmittedFileName();
InputStream fileContent = filePart.getInputStream();
// ... (do your job here)
}
Sunucu uygulaması 3.1 henüz üzerinde değilken, el ile gönderilen dosya
Part#getSubmittedFileName()
Sunucu uygulaması 3.1 tanıtıldı (Tomcat 8, WildFly 4, vb Önemli olan 8,) olduğunu unutmayın. Eğer Sunucu uygulaması 3.1 henüz varsa, o zaman ek yarar bir yöntem gönderilen dosya adı almanız gerekir.
private static String getSubmittedFileName(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
String fileName = cd.substring(cd.indexOf('=') 1).trim().replace("\"", "");
return fileName.substring(fileName.lastIndexOf('/') 1).substring(fileName.lastIndexOf('\\') 1); // MSIE fix.
}
}
return null;
}
String fileName = getSubmittedFileName(filePart);
Dosya adı almak için MSIE olarak düzeltmeyi unutmayın. Bu tarayıcı yanlış dosya adı yerine adını birlikte tam dosya yolunu gönderir.
Sunucu uygulaması üzerinde değilken 3.0 henüz, kullan Apache Commons FileUpload
Eğer 3.0 henüz (bu yükseltme zamanı gelmedi mi?) Sunucu uygulaması, oldun. yaygın bir uygulama Apache Commons FileUpload kullanımı multpart ayrıştırmak için bilgi talep formu yapın. User Guide mükemmel ve 68* *(dikkatle iki geçmesi). Ayrıca O ' Reilly var("cos") MultipartRequest
, ama (küçük) bazı hatalar var ve aktif olarak yıllardır artık korunmaz. Bunu kullanarak tavsiye etmem. Apache Commons FileUpload hala aktif olarak korunur ve çok olgun şu anda.
Apache Commons FileUpload kullanmak için aşağıdaki dosyaları /WEB-INF/lib
en az olması gerekir:
İlk denemeniz commons IO unuttum çünkü büyük olasılıkla başarısız oldu.
Burada UploadServlet
Apache Commons FileUpload kullanarak gibi görünebilir nasıl bir açılış için
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldName = item.getFieldName();
String fieldValue = item.getString();
// ... (do your job here)
} else {
// Process form file field (input type="file").
String fieldName = item.getFieldName();
String fileName = FilenameUtils.getName(item.getName());
InputStream fileContent = item.getInputStream();
// ... (do your job here)
}
}
} catch (FileUploadException e) {
throw new ServletException("Cannot parse multipart request.", e);
}
// ...
}
Aynı isteği üzerine*37, , , *, getReader()
, *getInputStream()
getParameterValues()
*38 vb önceden aramadın çok önemli. Aksi takdirde sunucu uygulaması kap ve vücut okuma isteği ayrıştırmak ve böylece Apache Commons FileUpload boş bir istek vücut olsun. Ayrıca bir bakın.Ç. ServletFileUpload#parseRequest(request) returns an empty list.
FilenameUtils#getName()
not. Bu dosya adını almak için MSIE bir düzeltme. Bu tarayıcı yanlış dosya adı yerine adını birlikte tam dosya yolunu gönderir.
Alternatif olarak da şal bu bir Filter
ayrıştırır hepsini otomatik olarak yüklenecektir ve malı geri parametermap isteği üzerine böylece devam edersin kullanarak request.getParameter()
her zamanki gibi, ve almak yüklenen dosya ile request.getAttribute()
. You can find an example in this blog article.
getParameter()
null
dönen GlassFish3 hata için geçici çözüm
Önemli olan daha eski sürüm 3.1.2 getParameter()
null
döndürür a bug neyin olduğunu unutmayın. Böyle bir kap yönlendirilmesi ve yükseltme yapamıyorsanız, o zaman bu programı yöntemin yardımıyla getPart()
değeri ayıklamak gerekir:
private static String getValue(Part part) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8"));
StringBuilder value = new StringBuilder();
char[] buffer = new char[1024];
for (int length = 0; (length = reader.read(buffer)) > 0;) {
value.append(buffer, 0, length);
}
return value.toString();
}
String description = getValue(request.getPart("description")); // Retrieves <input type="text" name="description">
Tasarruf yüklenen dosya (getRealPath()
kullanmayın ya part.write()
!)
Disk veya veritabanına düzgün InputStream
elde edilen (yukarıda kod parçacıkları gösterildiği gibi fileContent
değişken) kaydetme hakkında ayrıntı için aşağıdaki adreslere Başkanı:
- Recommended way to save uploaded files in a servlet application
- How to upload an image and save it in database?
- How to convert Part to Blob, so I can store it in MySQL?
Yüklenen dosya hizmet
Doğru istemciye disk veya veritabanı geri kaydedilen dosya hizmet detay için aşağıdaki adreslere Başkanı:
- Load images from outside of webapps / webcontext / deploy folder using <h:graphicImage> or <img> tag
- How to retrieve and display images from a database in a JSP page?
- Simplest way to serve static data from outside the application server in a Java web application
- Abstract template for static resource servlet supporting HTTP caching
Form Ajaxifying
Ajax (jQuery) kullanarak yüklemek için, aşağıdaki cevaplar için kafa. Form verilerini toplamak için sunucu kodu bunun için değiştirilmesi gerekir! Ancak bu şekilde size cevap olabilir değişti, ama bu oldukça önemsiz (yani yerine yönlendirme için JSP, sadece baskı bazı JSON veya XML, hatta düz metin olarak, ne olursa olsun bir senaryoyu sorumlu Ajax çağrı bekliyor).
- How to upload files to server using JSP/Servlet and Ajax?
- sending a file as multipart through xmlHttpRequest
- HTML5 File Upload to Java Servlet
Umarım bu yardımcı olur :)
Nasıl yürütme SAVAŞTA ek açıklamaları ...
Nasıl benim sunucu uygulaması JUnit ku...
Nasıl bir UİView uç bir dosya Interfac...
Nasıl bir sayfa Javascript kullanarak ...
Nasıl Java sunucu uygulaması bir filtr...