Java 如何以编程方式将文件上载到网站?

Java 如何以编程方式将文件上载到网站?,java,jsf,file-upload,Java,Jsf,File Upload,我必须上传一个文件到一个服务器,该服务器只公开一个带有文件上传按钮(通过http)的jsf网页。我必须自动执行一个生成文件并将文件上载到服务器的过程(作为java独立过程完成)。遗憾的是,必须上载文件的服务器不提供FTP或SFTP。有办法做到这一点吗 谢谢, Richie尝试使用HttpClient,我认为它描述了您想要的,在底部有一个标题为“使用基于HttpClient的文件上载”的部分 希望这有帮助。可能该网页只是向服务器发送一个包含表单内容的POST请求。您可以轻松地从Java发送这样的P

我必须上传一个文件到一个服务器,该服务器只公开一个带有文件上传按钮(通过http)的jsf网页。我必须自动执行一个生成文件并将文件上载到服务器的过程(作为java独立过程完成)。遗憾的是,必须上载文件的服务器不提供FTP或SFTP。有办法做到这一点吗

谢谢, Richie

尝试使用HttpClient,我认为它描述了您想要的,在底部有一个标题为“使用基于HttpClient的文件上载”的部分


希望这有帮助。

可能该网页只是向服务器发送一个包含表单内容的POST请求。您可以轻松地从Java发送这样的POST请求,而无需使用该页面。例如,显示了一个从Java发送POST请求的示例,您需要做的是检查页面上的HTML并确定发布表单所需的参数。它可能看起来像这样:

<form action="/RequestURL">
<input type=file name=file1>
<input type=textbox name=value1>
</form>

请记住,编写页面的人可能会进行一些检查,以确保POST请求来自同一站点。在这种情况下,您可能会遇到麻烦,您可能需要正确设置用户代理。

您可以尝试使用它。它提供了一个非常简单的API来模拟浏览器操作。我已经将这种方法用于类似的需求。这很容易。您应该试一试。

当以编程方式提交JSF生成的表单时,您需要确保考虑以下三点:

  • 维护HTTP会话(当然,如果网站已打开JSF服务器端状态保存)
  • 发送
    javax.faces.ViewState
    隐藏字段的名称-值对
  • 发送实际要按下的按钮的名称-值对
  • 否则,可能根本不会调用该操作。对于残余物来说,它与“常规”形式没有什么不同。流程基本如下:

    • 在带有表单的页面上发送GET请求
    • 提取JSESSIONID cookie
    • 从响应中提取
      javax.faces.ViewState
      隐藏字段的值。如有必要(确保它有一个动态生成的名称,因此可能会更改每个请求),提取输入文件字段的名称和提交按钮。动态生成的id/名称可通过
      j_id
      前缀识别
    • 准备
      多部分/表单数据
      POST请求
    • 在该请求上设置JSESSIONID cookie(如果不是
      null
    • 设置
      javax.faces.ViewState
      隐藏字段和按钮的名称-值对
    • 设置要上载的文件
    您可以使用任何HTTP客户端库来执行该任务。标准JavaSEAPI为此提供了
    Java.net.URLConnection
    ,即。为了减少冗长的代码,您可以使用来执行HTTP请求、管理cookie以及从HTML中提取数据

    下面是一个开始示例,假设页面只有一个
    (否则需要在Jsoup的CSS选择器中包含该表单的唯一标识符):


    我试过了,但没有成功。我建立了一个类似的虚拟网站。当我提交jsf页面的post响应时,我得到了200个OK响应。出于某种原因,它没有调用submit方法。我在服务器中为submit方法设置了一个断点,但调用从未到达该断点。很难指出到目前为止给出的信息的真正问题。你知道为了让代码示例在特定网站上运行,你必须对代码示例进行哪些更改吗?是的。我更改了URL和submit按钮值以匹配我的网页。我还更改了要上载的文件路径。我向实体“%formname%\u submit”添加了另一个部分,字符串值为1,该部分开始工作。另一个隐藏参数没有在multipart中设置,就是这个-试试我的运气,瞧!谢谢你,伙计,你真是个省钱的人JSoup是一个很酷的api!哦,那一定是一个旧的JSF1.xWebApp。对不起,我没想到。很高兴你想到了。是的,的确如此,Jsoup非常圆滑:)谢谢大副的回答。我曾经尝试过这个,但是因为它是一个jsf应用程序,我必须按照BalusC在回答中指出的那样设置隐藏参数。你能保留它的工作示例代码吗。
    String data = URLEncoder.encode("value1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
    data += "&" + URLEncoder.encode("file1", "UTF-8") + "=" + URLEncoder.encode(FileData, "UTF-8");
    
    // Send data
    URL url = new URL("http://servername.com/RequestURL");
    URLConnection conn = url.openConnection();
    conn.setDoOutput(true);
    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
    wr.write(data);
    wr.flush();
    wr.close();
    
    String url = "http://localhost:8088/playground/test.xhtml";
    String viewStateName = "javax.faces.ViewState";
    String submitButtonValue = "Upload"; // Value of upload submit button.
    
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext httpContext = new BasicHttpContext();
    httpContext.setAttribute(ClientContext.COOKIE_STORE, new BasicCookieStore());
    
    HttpGet httpGet = new HttpGet(url);
    HttpResponse getResponse = httpClient.execute(httpGet, httpContext);
    Document document = Jsoup.parse(EntityUtils.toString(getResponse.getEntity()));
    String viewStateValue = document.select("input[type=hidden][name=" + viewStateName + "]").val();
    String uploadFieldName = document.select("input[type=file]").attr("name");
    String submitButtonName = document.select("input[type=submit][value=" + submitButtonValue + "]").attr("name");
    
    File file = new File("/path/to/file/you/want/to/upload.ext");
    InputStream fileContent = new FileInputStream(file);
    String fileContentType = "application/octet-stream"; // Or whatever specific.
    String fileName = file.getName();
    
    HttpPost httpPost = new HttpPost(url);
    MultipartEntity entity = new MultipartEntity();
    entity.addPart(uploadFieldName, new InputStreamBody(fileContent, fileContentType, fileName));
    entity.addPart(viewStateName, new StringBody(viewStateValue));
    entity.addPart(submitButtonName, new StringBody(submitButtonValue));
    httpPost.setEntity(entity);
    HttpResponse postResponse = httpClient.execute(httpPost, httpContext);
    // ...