无法使用Struts将文件上传到MySQL

时间:2014-03-27 17:26:16

标签: java mysql jsp struts

我一直在尝试使用blob数据类型将文件上传到MySQL数据库。 这是我的JSP页面

<body>
    <c:choose>
        <c:when test="${not empty sessionScope.username}">
            <form method="post" enctype="multipart/form-data" action="postResume.do">
                <h4>Please paste your resume below</h4>
                <input name="t1" type="file"/>
                <input type="submit" value="Post"/>
            </form>                
        </c:when>
        <c:otherwise>
            <h1>Please Login First</h1>
        </c:otherwise>
    </c:choose>
</body>

bean有一个getter和setter方法

public class CandyResume extends org.apache.struts.action.ActionForm {

    private FormFile t1;

    public FormFile getT1() {
        return t1;
    }
    public void setT1(FormFile t1) {
        this.t1 = t1;
    }
}

bean actionform具有以下代码

public class CandyResumeAction extends org.apache.struts.action.Action {

@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {

    String result = null;
    HttpSession session = request.getSession();
    CandyResume val = (CandyResume)form;
    Connection con = DBConnection.DBConnection.justConnect();
    try{            
        FormFile formFile = val.getT1();
        File file = new File(formFile.getFileName());
        FileInputStream fin = new FileInputStream(file);
    //    String filePath = getServlet().getServletContext().getRealPath("") +"/"+formFile.getFileName();
        Integer filesize = formFile.getFileSize();
        PreparedStatement ps = con.prepareStatement("INSERT INTO seek_resumeupdate VALUES(?,?)");
        ps.setInt(1, Integer.parseInt(session.getId()));
        ps.setBinaryStream(2, fin, filesize);
        int insert = ps.executeUpdate();
        if(insert!=0)
            result = "uploaded";
        else 
            result = "failed";
    }catch(SQLException ex){
        ex.printStackTrace();
    }
    return mapping.findForward(result);
 }
}

如果我手动指定路径,代码工作正常,但如果我需要用户上传所需文件则不行。它给了我以下错误。这是堆栈跟踪。

java.io.FileNotFoundException: Aman_Resume (1).doc (The system cannot find the file specified)
java.io.FileInputStream.open(Native Method)
java.io.FileInputStream.<init>(FileInputStream.java:138)
Action.CandyResumeAction.execute(CandyResumeAction.java:36)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

为什么我会看到此错误以及为什么在手动指定文件路径时它会起作用?

2 个答案:

答案 0 :(得分:0)

您真的不想将文件上传到服务器。您只想将一些文件信息存储到数据库中。 但是在您的操作类中,您试图找出将文件存储在服务器中的服务器路径,这对您的要求是不必要的。

try {
            CandyResume resumeForm = (CandyResume) form;
            FormFile formFile = resumeForm.getT1();
            Connection con = DBConnection.DBConnection.justConnect();
            /*
             * this is where you are going to upload your file to . You cannot
             * expect your file in this path. note that this is your File
             * Upload Action class
             */
            // getting the server's upload directory real path name

            // If your intention is not to upload on server, then there is no need of the below line.
            // You already have your file which is 'formFile'

            String filePath = getServlet().getServletContext().getRealPath("");

            /*
             * check the value of filePath because the method returns null if the
             * container is unable to translate to a real path , in case you intend
             * to pass a parameter
             */

            // for fileName
            String fileName = formFile.getFileName();

            // do what you want to do with the file which is 'formFile'


        } catch (Exception ex) {
            ex.printStackTrace();
        }

还有一件事虽然与您的问题无关,但请不要将该属性命名为t1,而要将其命名为CandyResume.java中的private FormFile t1。为有意义的命名命名private FormFile file之类的东西

答案 1 :(得分:0)

这是问题的解决方案,以便其他人看到类似的东西可以得到一个提示。唯一的更改是在Struts Action文件中。

CandyResumeAction.java

@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {

    String result = null;
    HttpSession session = request.getSession();
    String name = (String)session.getAttribute("username");
    int a = Integer.parseInt(name);
    CandyResume val = (CandyResume)form;
    Connection con = DBConnection.DBConnection.justConnect();
    try{            
        FormFile formFile = val.getFile();
        InputStream fin = formFile.getInputStream();
        PreparedStatement ps = con.prepareStatement("INSERT INTO seek_resumeupdate VALUES(?,?)");
        ps.setInt(1, a);
        ps.setBlob(2, fin);
        int insert = ps.executeUpdate();
        if(insert!=0)
            result = "uploaded";
        else 
            result = "failed";
    }catch(SQLException ex){
        ex.printStackTrace();
    }
    return mapping.findForward(result);
}

问题恰巧是我设置的会话属性,并将其与getId()函数混淆。