จะอัพโหลดไฟล์ไปยังเซิร์ฟเวอร์โดยใช้ JSP / Servlet ได้อย่างไร


688

ฉันจะอัพโหลดไฟล์ไปยังเซิร์ฟเวอร์โดยใช้ JSP / Servlet ได้อย่างไร ฉันลองสิ่งนี้:

<form action="upload" method="post">
    <input type="text" name="description" />
    <input type="file" name="file" />
    <input type="submit" />
</form>

อย่างไรก็ตามฉันได้รับชื่อไฟล์เท่านั้นไม่ใช่เนื้อหาของไฟล์ เมื่อฉันเพิ่ม enctype="multipart/form-data"ไป<form>แล้วก็request.getParameter()กลับnullมา

ในระหว่างการวิจัยฉัน stumbled เมื่อApache ทั่วไป FileUpload ฉันลองสิ่งนี้:

FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.

น่าเสียดายที่ servlet ส่งข้อยกเว้นโดยไม่มีข้อความที่ชัดเจนและสาเหตุ นี่คือ 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)

บางทีบทความนี้จะเป็นประโยชน์: baeldung.com/upload-file-servlet
Adam Gerard

คำตอบ:


1193

บทนำ

ในการเรียกดูและเลือกไฟล์สำหรับการอัปโหลดคุณต้องมี<input type="file">ฟิลด์HTML ในแบบฟอร์ม ตามที่ระบุไว้ในข้อกำหนด HTMLคุณจะต้องใช้POSTวิธีการและแอตทริบิวต์ของรูปแบบจะต้องมีการตั้งค่าให้enctype"multipart/form-data"

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="text" name="description" />
    <input type="file" name="file" />
    <input type="submit" />
</form>

หลังจากส่งแบบฟอร์มดังกล่าวแล้วข้อมูลรูปแบบไบนารีหลายส่วนจะมีอยู่ในเนื้อหาคำขอในรูปแบบที่แตกต่างจากเมื่อenctypeไม่ได้ตั้งค่า

ก่อน Servlet 3.0 Servlet API multipart/form-dataไม่ได้รับการสนับสนุนโดยกำเนิด สนับสนุนเฉพาะรูปแบบเริ่มต้นของapplication/x-www-form-urlencodedประเภท request.getParameter()และภริยาจะกลับมาทั้งหมดnullเมื่อใช้ข้อมูลในแบบฟอร์ม multipart นี่คือจุดที่Apache Commons FileUpload อัพโหลดเข้ามาในรูปภาพ

อย่าแยกวิเคราะห์ด้วยตนเอง!

ในทางทฤษฎีคุณสามารถแยกวิเคราะห์คำขอตามตัวคุณเองServletRequest#getInputStream()ได้ แต่นี้คือการทำงานที่แม่นยำและน่าเบื่อที่ต้องมีความรู้ที่แม่นยำของRFC2388 คุณไม่ควรพยายามทำสิ่งนี้ด้วยตัวเองหรือทำสำเนาบางรหัสที่ไม่มีห้องสมุดที่ผลิตเองในที่อื่นบนอินเทอร์เน็ต แหล่งข้อมูลออนไลน์จำนวนมากล้มเหลวอย่างหนักในเรื่องนี้เช่น roseindia.net ดูเพิ่มเติมอัปโหลดไฟล์ PDF คุณควรใช้ไลบรารี่จริงที่ผู้ใช้หลายล้านคนใช้ (และผ่านการทดสอบโดยปริยาย!) ห้องสมุดดังกล่าวได้พิสูจน์ให้เห็นถึงความแข็งแกร่ง

เมื่อคุณใช้ Servlet 3.0 หรือใหม่กว่าอยู่แล้วให้ใช้ native API

หากคุณใช้ Servlet 3.0 เป็นอย่างน้อย (Tomcat 7, Jetty 9, JBoss AS 6, GlassFish 3 เป็นต้น) คุณสามารถใช้ API มาตรฐานที่มีให้HttpServletRequest#getPart()เพื่อรวบรวมรายการข้อมูลแบบหลายส่วน (การใช้งาน Servlet 3.0 ส่วนใหญ่ใช้ Apache จริง คอมมอนส์ไฟล์อัปโหลดภายใต้หน้าปกสำหรับสิ่งนี้!) นอกจากนี้ยังมีเขตข้อมูลฟอร์มgetParameter()ปกติด้วยวิธีปกติ

ขั้นแรกให้คำอธิบายประกอบเซิร์ฟเล็ตของคุณด้วย@MultipartConfigเพื่อให้สามารถรับรู้และสนับสนุนmultipart/form-dataคำขอและgetPart()ไปทำงาน:

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
    // ...
}

จากนั้นดำเนินการdoPost()ดังต่อไปนี้:

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 = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
    InputStream fileContent = filePart.getInputStream();
    // ... (do your job here)
}

Path#getFileName()หมายเหตุ นี่คือการแก้ไข MSIE ที่จะได้รับชื่อไฟล์ เบราว์เซอร์นี้ส่งเส้นทางไฟล์แบบเต็มอย่างไม่ถูกต้องไปตามชื่อแทนที่จะเป็นเพียงชื่อไฟล์

ในกรณีที่คุณมีการ<input type="file" name="file" multiple="true" />อัปโหลดหลายไฟล์ให้รวบรวมไว้ด้านล่าง (น่าเสียดายที่ไม่มีวิธีการดังกล่าวrequest.getParts("file")):

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ...
    List<Part> fileParts = request.getParts().stream().filter(part -> "file".equals(part.getName()) && part.getSize() > 0).collect(Collectors.toList()); // Retrieves <input type="file" name="file" multiple="true">

    for (Part filePart : fileParts) {
        String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
        InputStream fileContent = filePart.getInputStream();
        // ... (do your job here)
    }
}

เมื่อคุณไม่ได้อยู่ใน Servlet 3.1 ให้รับชื่อไฟล์ที่ส่งด้วยตนเอง

โปรดทราบว่าPart#getSubmittedFileName()เปิดตัวใน Servlet 3.1 (Tomcat 8, Jetty 9, WildFly 8, GlassFish 4, ฯลฯ ) หากคุณยังไม่ได้ใช้ Servlet 3.1 คุณต้องมีวิธีการอรรถประโยชน์เพิ่มเติมเพื่อรับชื่อไฟล์ที่ส่ง

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);

หมายเหตุการแก้ไข MSIE เป็นการขอรับชื่อแฟ้ม เบราว์เซอร์นี้ส่งเส้นทางไฟล์แบบเต็มอย่างไม่ถูกต้องไปตามชื่อแทนที่จะเป็นเพียงชื่อไฟล์

เมื่อคุณไม่ได้ใช้ Servlet 3.0 ให้ใช้ Apache Commons FileUpload

หากคุณยังไม่ได้ใช้ Servlet 3.0 (ยังไม่ถึงเวลาที่จะอัพเกรดหรือไม่) วิธีปฏิบัติทั่วไปคือการใช้Apache Commons FileUploadเพื่อแยกการร้องขอข้อมูลแบบฟอร์มหลายส่วน มันมีคู่มือผู้ใช้ที่ดีเยี่ยมและคำถามที่พบบ่อย (ผ่านทั้งสองอย่างระมัดระวัง) นอกจากนี้ยังมี O'Reilly (" cos ") MultipartRequestแต่มีข้อผิดพลาด (เล็กน้อย) และไม่ได้รับการบำรุงรักษาอีกต่อไปเป็นเวลาหลายปี ฉันไม่แนะนำให้ใช้ Apache Commons FileUpload ยังคงได้รับการบำรุงรักษาอย่างแข็งขันและในปัจจุบันมีความสมบูรณ์มาก

ในการใช้ Apache Commons FileUpload คุณต้องมีไฟล์ต่อไปนี้อย่างน้อยใน webapp ของคุณ/WEB-INF/lib:

ความพยายามครั้งแรกของคุณล้มเหลวเนื่องจากคุณลืม IO ทั่วไป

นี่คือตัวอย่างของการแจ้งกำหนดการลักษณะdoPost()ของคุณUploadServletเมื่อใช้ Apache Commons FileUpload:

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);
    }

    // ...
}

มันเป็นสิ่งสำคัญมากที่คุณไม่ได้โทรgetParameter(), getParameterMap(), getParameterValues(), getInputStream(), getReader()ฯลฯ ตามคำขอเดียวกันก่อน มิฉะนั้นภาชนะ servlet จะอ่านและแยกเนื้อหาคำขอและ Apache Commons FileUpload จะได้รับร่างกายคำขอว่าง ดูเพิ่มเติมอ่าวServletFileUpload # parseRequest (ขอ) ส่งกลับรายการที่ว่างเปล่า

FilenameUtils#getName()หมายเหตุ นี่คือการแก้ไข MSIE ที่จะได้รับชื่อไฟล์ เบราว์เซอร์นี้ส่งเส้นทางไฟล์แบบเต็มอย่างไม่ถูกต้องไปตามชื่อแทนที่จะเป็นเพียงชื่อไฟล์

หรือคุณยังสามารถห่อนี้ทั้งหมดในFilterที่แยกมันทั้งหมดโดยอัตโนมัติและนำกลับสิ่งที่อยู่ใน parametermap ของการร้องขอเพื่อให้คุณสามารถดำเนินการโดยใช้วิธีการปกติและดึงไฟล์ที่อัปโหลดโดยrequest.getParameter() คุณสามารถค้นหาตัวอย่างในบทความบล็อกนี้request.getAttribute()

วิธีแก้ปัญหาสำหรับข้อผิดพลาด GlassFish3 getParameter()ยังคงกลับมาnull

หมายเหตุว่ารุ่น Glassfish เก่ากว่า 3.1.2 มีข้อผิดพลาดในประเด็นผลตอบแทนยังคงgetParameter() nullหากคุณกำหนดเป้าหมายไปที่คอนเทนเนอร์ดังกล่าวและไม่สามารถอัปเกรดได้คุณจะต้องแยกค่าจากgetPart()ด้วยความช่วยเหลือของวิธีการยูทิลิตี้นี้:

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">

กำลังบันทึกไฟล์ที่อัปโหลด (อย่าใช้getRealPath()หรือpart.write()!)

มุ่งไปที่คำตอบต่อไปนี้เพื่อดูรายละเอียดเกี่ยวกับการบันทึกที่ได้รับInputStream( fileContentตัวแปรตามที่แสดงในตัวอย่างโค้ดข้างต้น) ไปยังดิสก์หรือฐานข้อมูล:

กำลังแสดงไฟล์ที่อัพโหลด

ไปที่คำตอบต่อไปนี้เพื่อรับทราบรายละเอียดเกี่ยวกับการให้บริการไฟล์ที่ถูกบันทึกอย่างถูกต้องจากดิสก์หรือฐานข้อมูลกลับไปยังไคลเอนต์:

Ajaxifying แบบฟอร์ม

ตรงไปที่คำตอบต่อไปนี้วิธีการอัพโหลดโดยใช้ Ajax (และ jQuery) โปรดทราบว่ารหัส servlet เพื่อรวบรวมข้อมูลแบบฟอร์มไม่จำเป็นต้องเปลี่ยนแปลงสำหรับสิ่งนี้! เฉพาะวิธีที่คุณตอบกลับอาจเปลี่ยนแปลงได้ แต่สิ่งนี้ค่อนข้างเล็กน้อย (เช่นแทนที่จะส่งต่อไปยัง JSP เพียงพิมพ์ JSON หรือ XML หรือข้อความธรรมดาขึ้นอยู่กับสิ่งที่สคริปต์ที่รับผิดชอบในการเรียก Ajax)


หวังว่าทั้งหมดนี้จะช่วย :)


ขอโทษที่ฉันเห็นrequest.getParts("file")และสับสน x_x
Kagami Sascha Rosylight

ด้วย Servlet 3.0 หากMultipartConfigเงื่อนไขถูกละเมิด (เช่นmaxFileSize:) การโทรrequest.getParameter()จะส่งคืนค่าว่าง นี่คือจุดประสงค์หรือไม่ จะเกิดอะไรขึ้นถ้าฉันได้รับพารามิเตอร์ (ข้อความ) ปกติก่อนโทรgetPart(และตรวจสอบIllegalStateException) นี้ทำให้เกิดจะถูกโยนก่อนที่ผมจะมีโอกาสที่จะตรวจสอบได้NullPointerException IllegalStateException
ทั้ว

@BalusC ฉันสร้างโพสต์ที่เกี่ยวข้องกับเรื่องนี้คุณมีความคิดว่าฉันสามารถดึงข้อมูลเพิ่มเติมจาก File API webKitDirectory ได้อย่างไร รายละเอียดเพิ่มเติมได้ที่นี่stackoverflow.com/questions/45419598/…
Rapster

หากคุณไม่ได้ใช้ Servlet 3.0 และใช้เคล็ดลับ FileUpload ฉันพบว่าคุณไม่สามารถอ่านไฟล์จากคำขอมากกว่าหนึ่งครั้ง หากคุณต้องการฟังก์ชั่นนี้คุณอาจต้องการดู MultiPartFilter ของ Spring โพสต์นี้มีตัวอย่างการทำงานที่ดี: stackoverflow.com/a/21448087/1048376
splashout

1
ใช่ถ้ามีคนพยายามในการใช้รหัสใน 3.0 ส่วนที่มีแมวตัวผู้ 7 พวกเขาอาจจะประสบปัญหาในString fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.ส่วนที่คล้ายกับฉัน
raviraja

26

หากคุณบังเอิญใช้ Spring MVC นี่คือวิธี: (ฉันจะออกจากที่นี่ในกรณีที่มีคนพบว่ามีประโยชน์)

ใช้แบบฟอร์มพร้อมenctypeชุดคุณลักษณะเป็น " multipart/form-data" (เหมือนกับคำตอบของ BalusC)

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="Upload"/>
</form>

ในตัวควบคุมของคุณให้จับคู่พารามิเตอร์คำขอfileเพื่อMultipartFileพิมพ์ดังนี้:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public void handleUpload(@RequestParam("file") MultipartFile file) throws IOException {
    if (!file.isEmpty()) {
            byte[] bytes = file.getBytes(); // alternatively, file.getInputStream();
            // application logic
    }
}

คุณจะได้รับชื่อไฟล์และขนาดโดยใช้MultipartFile's และgetOriginalFilename()getSize()

ฉันได้ทำการทดสอบด้วยเวอร์ชั่นสปริง4.1.1.RELEASEแล้ว


ถ้าฉันไม่ผิดนี้ต้องให้คุณกำหนดค่าถั่วในการตั้งค่าเซิร์ฟเวอร์แอพลิเคชันของคุณ ...
เคนนี Worden

11

คุณต้องการcommon-io.1.4.jarไฟล์ที่จะรวมอยู่ในlibไดเรกทอรีของคุณหรือถ้าคุณกำลังทำงานในโปรแกรมแก้ไขใด ๆ เช่น NetBeans คุณจะต้องไปที่คุณสมบัติโครงการและเพิ่มไฟล์ JAR และคุณจะทำ

ในการรับcommon.io.jarไฟล์เพียง google มันหรือเพียงไปที่เว็บไซต์Apache Tomcatที่คุณได้รับตัวเลือกสำหรับการดาวน์โหลดไฟล์นี้ฟรี แต่จำไว้อย่างหนึ่ง: ดาวน์โหลดไฟล์ ZIP binary ถ้าคุณเป็นผู้ใช้ Windows


ไม่สามารถหาแต่.jar .zipคุณหมายถึง.zipอะไร
Malwinder Singh

10

ไม่มีคอมโพเนนต์หรือไลบรารีภายนอกใน Tomcat 6 o 7

การเปิดใช้งานการอัปโหลดในไฟล์web.xml :

http://joseluisbz.wordpress.com/2014/01/17/manually-installing-php-tomcat-and-httpd-lounge/#Enabling%20File%20Uploads

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <multipart-config>
      <max-file-size>3145728</max-file-size>
      <max-request-size>5242880</max-request-size>
    </multipart-config>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>

ตามที่คุณเห็น :

    <multipart-config>
      <max-file-size>3145728</max-file-size>
      <max-request-size>5242880</max-request-size>
    </multipart-config>

การอัพโหลดไฟล์โดยใช้ JSP ไฟล์:

ในไฟล์ html

<form method="post" enctype="multipart/form-data" name="Form" >

  <input type="file" name="fFoto" id="fFoto" value="" /></td>
  <input type="file" name="fResumen" id="fResumen" value=""/>

ในไฟล์ JSPหรือServlet

    InputStream isFoto = request.getPart("fFoto").getInputStream();
    InputStream isResu = request.getPart("fResumen").getInputStream();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte buf[] = new byte[8192];
    int qt = 0;
    while ((qt = isResu.read(buf)) != -1) {
      baos.write(buf, 0, qt);
    }
    String sResumen = baos.toString();

แก้ไขรหัสของคุณกับความต้องการของเซิร์ฟเล็ตเช่นสูงสุดขนาดไฟล์ , Max-คำขอขนาด และตัวเลือกอื่น ๆ ที่คุณสามารถที่จะตั้ง ...


9

ฉันกำลังใช้ Servlet ทั่วไปสำหรับทุกรูปแบบ Html ว่ามีไฟล์แนบหรือไม่ Servlet นี้ส่งคืนTreeMapตำแหน่งที่คีย์คือชื่อ jsp พารามิเตอร์และค่าคืออินพุตของผู้ใช้และบันทึกสิ่งที่แนบมาทั้งหมดในไดเรกทอรีคงที่และหลังจากนั้นคุณเปลี่ยนชื่อไดเรกทอรีที่คุณเลือกการเชื่อมต่อที่นี่คือส่วนต่อประสานที่กำหนดเองของเรา ฉันคิดว่านี่จะช่วยคุณได้

public class ServletCommonfunctions extends HttpServlet implements
        Connections {

    private static final long serialVersionUID = 1L;

    public ServletCommonfunctions() {}

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
            IOException {}

    public SortedMap<String, String> savefilesindirectory(
            HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        // Map<String, String> key_values = Collections.synchronizedMap( new
        // TreeMap<String, String>());
        SortedMap<String, String> key_values = new TreeMap<String, String>();
        String dist = null, fact = null;
        PrintWriter out = response.getWriter();
        File file;
        String filePath = "E:\\FSPATH1\\2KL06CS048\\";
        System.out.println("Directory Created   ????????????"
            + new File(filePath).mkdir());
        int maxFileSize = 5000 * 1024;
        int maxMemSize = 5000 * 1024;
        // Verify the content type
        String contentType = request.getContentType();
        if ((contentType.indexOf("multipart/form-data") >= 0)) {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // maximum size that will be stored in memory
            factory.setSizeThreshold(maxMemSize);
            // Location to save data that is larger than maxMemSize.
            factory.setRepository(new File(filePath));
            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            // maximum file size to be uploaded.
            upload.setSizeMax(maxFileSize);
            try {
                // Parse the request to get file items.
                @SuppressWarnings("unchecked")
                List<FileItem> fileItems = upload.parseRequest(request);
                // Process the uploaded file items
                Iterator<FileItem> i = fileItems.iterator();
                while (i.hasNext()) {
                    FileItem fi = (FileItem) i.next();
                    if (!fi.isFormField()) {
                        // Get the uploaded file parameters
                        String fileName = fi.getName();
                        // Write the file
                        if (fileName.lastIndexOf("\\") >= 0) {
                            file = new File(filePath
                                + fileName.substring(fileName
                                        .lastIndexOf("\\")));
                        } else {
                            file = new File(filePath
                                + fileName.substring(fileName
                                        .lastIndexOf("\\") + 1));
                        }
                        fi.write(file);
                    } else {
                        key_values.put(fi.getFieldName(), fi.getString());
                    }
                }
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }
        return key_values;
    }
}

@buhake ซินดิเฮ้สิ่งที่ควรจะ filepath ถ้า im ใช้เซิร์ฟเวอร์สดหรือฉันอาศัยอยู่ในโครงการของฉันโดยการอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์
Amans

2
ไดเรกทอรีใด ๆ ในเซิร์ฟเวอร์สดถ้าคุณเขียนรหัสเพื่อสร้างไดเรกทอรีใน servlet แล้วไดเรกทอรีจะถูกสร้างขึ้นในสด srver
รู้สึกดีและการเขียนโปรแกรม

8

สำหรับ Spring MVC ฉันพยายามเป็นเวลาหลายชั่วโมงและจัดการเพื่อให้มีเวอร์ชันที่ง่ายกว่าที่ใช้สำหรับการป้อนข้อมูลในแบบฟอร์มทั้งข้อมูลและรูปภาพ

<form action="/handleform" method="post" enctype="multipart/form-data">
  <input type="text" name="name" />
  <input type="text" name="age" />
  <input type="file" name="file" />
  <input type="submit" />
</form>

ควบคุมเพื่อจัดการ

@Controller
public class FormController {
    @RequestMapping(value="/handleform",method= RequestMethod.POST)
    ModelAndView register(@RequestParam String name, @RequestParam int age, @RequestParam MultipartFile file)
            throws ServletException, IOException {

        System.out.println(name);
        System.out.println(age);
        if(!file.isEmpty()){
            byte[] bytes = file.getBytes();
            String filename = file.getOriginalFilename();
            BufferedOutputStream stream =new BufferedOutputStream(new FileOutputStream(new File("D:/" + filename)));
            stream.write(bytes);
            stream.flush();
            stream.close();
        }
        return new ModelAndView("index");
    }
}

หวังว่าจะช่วย :)


คุณกรุณาแบ่งปันรูปแบบภาพที่เลือก db mysql และแสดงใน jsp / html ได้ไหม?
Ved Prakash

6

แหล่งที่มาอื่นของปัญหานี้เกิดขึ้นหากคุณใช้ Geronimo กับ Tomcat ในตัว ในกรณีนี้หลังจากทำซ้ำหลาย ๆ ครั้งในการทดสอบคอมมอนส์ - io และคอมมอนส์ - ไฟล์อัปโหลดปัญหาเกิดขึ้นจากแม่ classloader จัดการกับขวด jons สามัญ สิ่งนี้จะต้องมีการป้องกัน ความผิดพลาดเกิดขึ้นเสมอที่:

fileItems = uploader.parseRequest(request);

โปรดทราบว่าประเภทรายการของ fileItems มีการเปลี่ยนแปลงกับรุ่นปัจจุบันของคอมมอน-FileUpload ที่จะได้รับโดยเฉพาะเมื่อเทียบกับรุ่นก่อนที่มันเป็นทั่วไปList<FileItem>List

ฉันเพิ่มซอร์สโค้ดสำหรับคอมมอนส์ - ไฟล์อัปโหลดและคอมมอนส์ - ไอโอในโครงการ Eclipse ของฉันเพื่อติดตามข้อผิดพลาดที่เกิดขึ้นจริงและในที่สุดก็มีข้อมูลเชิงลึกบางอย่าง ขั้นแรกข้อยกเว้นการโยนเป็นประเภท Throwable ไม่ใช่ FileIOException ที่ระบุไว้หรือแม้แต่ข้อยกเว้น (สิ่งเหล่านี้จะไม่ถูกดักจับ) ประการที่สองข้อความแสดงข้อผิดพลาดจะทำให้งงงวยโดยระบุคลาสไม่พบเนื่องจาก Axis2 ไม่สามารถค้นหาคอมมอนส์ -o Axis2 ไม่ได้ใช้ในโครงการของฉันเลย แต่มีอยู่ในโฟลเดอร์ในไดเรกทอรีย่อยที่เก็บข้อมูลของ Geronimo ซึ่งเป็นส่วนหนึ่งของการติดตั้งมาตรฐาน

ในที่สุดฉันก็พบสถานที่ 1 แห่งที่วางวิธีแก้ปัญหาการทำงานซึ่งแก้ไขปัญหาของฉันได้สำเร็จ คุณต้องซ่อนไหจากพาเรนต์หลักในแผนการปรับใช้ สิ่งนี้ถูกใส่ใน geronimo-web.xml ด้วยไฟล์เต็มของฉันที่แสดงด้านล่าง

Pasted from <http://osdir.com/ml/user-geronimo-apache/2011-03/msg00026.html> 



<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web:web-app xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
    <dep:environment>
        <dep:moduleId>
            <dep:groupId>DataStar</dep:groupId>
            <dep:artifactId>DataStar</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>car</dep:type>
        </dep:moduleId>

<!--Don't load commons-io or fileupload from parent classloaders-->
        <dep:hidden-classes>
            <dep:filter>org.apache.commons.io</dep:filter>
            <dep:filter>org.apache.commons.fileupload</dep:filter>
        </dep:hidden-classes>
        <dep:inverse-classloading/>        


    </dep:environment>
    <web:context-root>/DataStar</web:context-root>
</web:web-app>

0

นี่คือตัวอย่างการใช้ apache คอมมอนส์ - ไฟล์อัปโหลด:

// apache commons-fileupload to handle file upload
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File(DataSources.TORRENTS_DIR()));
ServletFileUpload fileUpload = new ServletFileUpload(factory);

List<FileItem> items = fileUpload.parseRequest(req.raw());
FileItem item = items.stream()
  .filter(e ->
  "the_upload_name".equals(e.getFieldName()))
  .findFirst().get();
String fileName = item.getName();

item.write(new File(dir, fileName));
log.info(fileName);

0

วิธีที่ง่ายที่สุดอาจเกิดขึ้นกับไฟล์และตัวควบคุมอินพุตโดยไม่มีไลบรารีนับพันล้านรายการ:

  <%
  if (request.getContentType()==null) return;
  // for input type=text controls
  String v_Text = 
  (new BufferedReader(new InputStreamReader(request.getPart("Text1").getInputStream()))).readLine();    

  // for input type=file controls
  InputStream inStr = request.getPart("File1").getInputStream();
  char charArray[] = new char[inStr.available()];
  new InputStreamReader(inStr).read(charArray);
  String contents = new String(charArray);
  %>

-1

คุณสามารถอัปโหลดไฟล์โดยใช้ jsp / servlet

<form action="UploadFileServlet" method="post">
  <input type="text" name="description" />
  <input type="file" name="file" />
  <input type="submit" />
</form>

ในอีกด้านหนึ่งเซิร์ฟเวอร์ ใช้รหัสต่อไปนี้

     package com.abc..servlet;

import java.io.File;
---------
--------


/**
 * Servlet implementation class UploadFileServlet
 */
public class UploadFileServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public UploadFileServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.sendRedirect("../jsp/ErrorPage.jsp");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

            PrintWriter out = response.getWriter();
            HttpSession httpSession = request.getSession();
            String filePathUpload = (String) httpSession.getAttribute("path")!=null ? httpSession.getAttribute("path").toString() : "" ;

            String path1 =  filePathUpload;
            String filename = null;
            File path = null;
            FileItem item=null;


            boolean isMultipart = ServletFileUpload.isMultipartContent(request);

            if (isMultipart) {
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
                String FieldName = "";
                try {
                    List items = upload.parseRequest(request);
                    Iterator iterator = items.iterator();
                    while (iterator.hasNext()) {
                         item = (FileItem) iterator.next();

                            if (fieldname.equals("description")) {
                                description = item.getString();
                            }
                        }
                        if (!item.isFormField()) {
                            filename = item.getName();
                            path = new File(path1 + File.separator);
                            if (!path.exists()) {
                                boolean status = path.mkdirs();
                            }
                            /* START OF CODE FRO PRIVILEDGE*/

                            File uploadedFile = new File(path + Filename);  // for copy file
                            item.write(uploadedFile);
                            }
                        } else {
                            f1 = item.getName();
                        }

                    } // END OF WHILE 
                    response.sendRedirect("welcome.jsp");
                } catch (FileUploadException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                } 
            }   
    }

}

-1
DiskFileUpload upload=new DiskFileUpload();

จากวัตถุนี้คุณจะต้องได้รับรายการไฟล์และเขตข้อมูลแล้วคุณสามารถเก็บลงในเซิร์ฟเวอร์ดังนี้:

String loc="./webapps/prjct name/server folder/"+contentid+extension;
File uploadFile=new File(loc);
item.write(uploadFile);

-2

การส่งไฟล์หลายไฟล์สำหรับไฟล์ที่เราต้องใช้enctype="multipart/form-data"
และเพื่อส่งไฟล์หลายไฟล์ใช้ multiple="multiple"ในแท็กอินพุต

<form action="upload" method="post" enctype="multipart/form-data">
 <input type="file" name="fileattachments"  multiple="multiple"/>
 <input type="submit" />
</form>

2
เราจะไปเกี่ยวกับการทำ getPart ("fileattachments") เพื่อให้เราได้รับอาร์เรย์ของชิ้นส่วนแทน? ฉันไม่คิดว่า getPart สำหรับไฟล์หลาย ๆ ไฟล์จะใช้งานได้?
CyberMew

-2

หน้า HTML

<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="UploadServlet" method="post"
                        enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html> 

ไฟล์ SERVLET

// Import required java libraries
import java.io.*;
import java.util.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.output.*;

public class UploadServlet extends HttpServlet {

   private boolean isMultipart;
   private String filePath;
   private int maxFileSize = 50 * 1024;
   private int maxMemSize = 4 * 1024;
   private File file ;

   public void init( ){
      // Get the file location where it would be stored.
      filePath = 
             getServletContext().getInitParameter("file-upload"); 
   }
   public void doPost(HttpServletRequest request, 
               HttpServletResponse response)
              throws ServletException, java.io.IOException {
      // Check that we have a file upload request
      isMultipart = ServletFileUpload.isMultipartContent(request);
      response.setContentType("text/html");
      java.io.PrintWriter out = response.getWriter( );
      if( !isMultipart ){
         out.println("<html>");
         out.println("<head>");
         out.println("<title>Servlet upload</title>");  
         out.println("</head>");
         out.println("<body>");
         out.println("<p>No file uploaded</p>"); 
         out.println("</body>");
         out.println("</html>");
         return;
      }
      DiskFileItemFactory factory = new DiskFileItemFactory();
      // maximum size that will be stored in memory
      factory.setSizeThreshold(maxMemSize);
      // Location to save data that is larger than maxMemSize.
      factory.setRepository(new File("c:\\temp"));

      // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
      // maximum file size to be uploaded.
      upload.setSizeMax( maxFileSize );

      try{ 
      // Parse the request to get file items.
      List fileItems = upload.parseRequest(request);

      // Process the uploaded file items
      Iterator i = fileItems.iterator();

      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet upload</title>");  
      out.println("</head>");
      out.println("<body>");
      while ( i.hasNext () ) 
      {
         FileItem fi = (FileItem)i.next();
         if ( !fi.isFormField () )  
         {
            // Get the uploaded file parameters
            String fieldName = fi.getFieldName();
            String fileName = fi.getName();
            String contentType = fi.getContentType();
            boolean isInMemory = fi.isInMemory();
            long sizeInBytes = fi.getSize();
            // Write the file
            if( fileName.lastIndexOf("\\") >= 0 ){
               file = new File( filePath + 
               fileName.substring( fileName.lastIndexOf("\\"))) ;
            }else{
               file = new File( filePath + 
               fileName.substring(fileName.lastIndexOf("\\")+1)) ;
            }
            fi.write( file ) ;
            out.println("Uploaded Filename: " + fileName + "<br>");
         }
      }
      out.println("</body>");
      out.println("</html>");
   }catch(Exception ex) {
       System.out.println(ex);
   }
   }
   public void doGet(HttpServletRequest request, 
                       HttpServletResponse response)
        throws ServletException, java.io.IOException {

        throw new ServletException("GET method used with " +
                getClass( ).getName( )+": POST method required.");
   } 
}

web.xml

คอมไพล์ดังกล่าวข้างต้น servlet UploadServlet และสร้างรายการที่ต้องการในไฟล์ web.xml ดังต่อไปนี้

<servlet>
   <servlet-name>UploadServlet</servlet-name>
   <servlet-class>UploadServlet</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>UploadServlet</servlet-name>
   <url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.