【问题标题】:How to upload a file with Struts2?如何使用 Struts2 上传文件?
【发布时间】:2015-02-02 22:35:01
【问题描述】:

我正在尝试通过 jsp 页面中的标签<s:file> 将图像放入 MySQL 数据库中(我使用的是 Struts 2):

<s:form action="carica" id="carica" style="display:none">
    <s:file id="carica" name="caricaimg"></s:file>
    <s:submit value="Carica" ></s:submit>
</s:form>

在我的课堂上我做了这个:

public String carica() throws SQLException, FileNotFoundException{
    Connessione();   // DB connection method
    System.out.print(caricaimg);
    File file = new File(caricaimg);
    InputStream fin = new java.io.FileInputStream(file);
    int fileLength = (int)file.length();
    PreparedStatement pstmt = con.prepareStatement("INSERT INTO Utenti (NomeImg, Immagine) VALUES (?, ?)");
    pstmt.setString(1, file.getName());
    pstmt.setBinaryStream (2, fin, fileLength);
    pstmt.executeUpdate();
    return "success";
}

一切看起来都不错,但是当我选择带有 &lt;s:file&gt; 的图像时,它只返回所选文件的名称,所以当我尝试将图像放入 DB 时,它会返回此错误

HTTP 状态 500 - ImgName.jpg(无法找到所选文件)

这是我的 struts.xml 文件

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <package name="Model" extends="struts-default">
      <action name="dati" class="Model.Registrazione" method="execute">
            <result name="success">/RegistrazioneRiuscita.jsp</result>
      </action>
      <action name="login">
            <result>/Login.jsp</result>
      </action>
      <action name="acces" class="Model.Registrazione" method="accesso">
            <result name="success">/LoginRiuscito.jsp</result>
            <result name="fail">/LoginFallito.jsp</result>
      </action>
      <action name="modifica" class="Model.Registrazione" method="modifica">
            <result name="success">/ModificaRiuscita.jsp</result>
            <result name="fail">/ModificaFallita.jsp</result>
      </action>
      <action name="elimina" class="Model.Registrazione" method="elimina">
            <result name="success">/EliminatoSuccesso.jsp</result>
      </action>
      <action name="carica" class="Model.Registrazione" method="carica">
            <result name="success">/index.jsp</result>
      </action>
      </package>
</struts>

这是将所选文件处理为method="POST"的部分

<action name="carica" class="Model.Registrazione" method="carica">
    <result name="success">/index.jsp</result>
</action>

【问题讨论】:

  • 您只能从用户的机器上获取文件名而不是路径,因为这会给用户带来安全风险。您不需要他们机器上的路径,也不应该希望它...因为您要将文件放在服务器上您想要的任何位置,而不是他们拥有它的位置。
  • 是的,但是如果没有路径,我如何将所选文件提供给 'File file = new File();" ?
  • 你必须将它保存到服务器,然后你就有一个完整的路径,它在服务器上的路径。您没有在实际处理 POST 文件的位置发布代码,但它应该已经这样做了。如果不是,那就有问题了。
  • 但是我使用的是Struts 2,我不需要写method="POST"。 (我编辑了主要问题,所以你可以看到我的 struts.xml 文件)
  • 我说的是服务器端部分,您实际上检索文件并保存它。哪里是?例如,变量caricaimg 显然是全局变量,你在哪里设置?

标签: java mysql jsp file-upload struts2


【解决方案1】:

不要使用包含这么多动作的同一个动作文件...它很快就会成为维护的噩梦。

顺便说一句,当您使用 Struts2 上传文件时,这一切都是自动的:您没有更改的默认拦截器堆栈使用文件上传拦截器来填充三个变量(一个带有文件本身的 File 元素,而不仅仅是假设您有 setter,则在您的 Actions 中为 fileName 和 contentType 提供两个字符串。

您的表单中也缺少正确的编码类型,二进制上传必须是multipart/form-data

那么应该是这样的:

JSP

<s:form action="carica" enctype="multipart/form-data">
    <s:file name="caricaimg" />
    <s:submit value="Carica" />
</s:form>

动作

private File caricaimg;
private String caricaimgFileName;
private String caricaimgContentType;

/* getters and setters here */

public String carica() throws SQLException, FileNotFoundException{
    Connessione();   // DB connection method
    System.out.print(caricaimg);

    // not needed -> caricaimg is already a file !!
    // File file = new File(caricaimg);
    // InputStream fin = new java.io.FileInputStream(file);
    // int fileLength = (int)file.length();

    InputStream fin = new java.io.FileInputStream(caricaimg);
    int fileLength = (int)caricaimg.length();
    PreparedStatement pstmt = con.prepareStatement("INSERT INTO Utenti (NomeImg, Immagine) VALUES (?, ?)");

    // not needed -> you already have the fileName
    // pstmt.setString(1, file.getName());

    pstmt.setString(1, caricaimgFileName);
    pstmt.setBinaryStream (2, fin, fileLength);
    pstmt.executeUpdate();

    // DON'T FORGET TO CLOSE THE STREAM !!
    fin.close();
    // ---------

    return "success";
}

阅读更多关于this related question

【讨论】:

  • 我在您回答前一分钟找到了解决方案。顺便说一句,您的修改不起作用,我不知道为什么,但它在这一行“ InputStream fin = new java.io.FileInputStream(caricaimg); ”上给出了错误
  • 我必须修改它,现在它只将选定的文件放在 db 上,我使用的是 Statement 而不是 PreparedStatement public String carica() throws SQLException{ Connessione(); Statement cmd = con.createStatement(); String query = "UPDATE Utenti SET Immagine = '"+caricaimg+"' WHERE Username = '"+username+"';"; cmd.executeUpdate(query); return "success"; }
  • NO, you can't。也永远不要在查询中连接这样的字符串以防止 SQL 注入。也就是说,答案中的代码应该可以正常工作,如果您在该行有异常,请发布异常(通过编辑您的答案,而不是在 cmets 中),而不是偏离其他甚至更糟糕的解决方案
  • 对不起,你的代码有效,昨天我忘了把 enctype="multipart/form-data" 放在 s:form 中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
相关资源
最近更新 更多