如何以编程方式将文件上传到网站?
我必须将文件上传到服务器,该服务器仅显示带有文件上传按钮的jsf网页(通过http)。 我必须自动化一个进程(作为java独立进程完成),它生成一个文件并将文件上传到服务器。然后,必须上传文件的服务器不提供FTP或SFTP。 有没有办法做到这一点?
谢谢,里奇
以编程方式提交JSF生成的表单时,您需要确保考虑以下3项内容:
- 维护HTTP会话(当然,如果网站启用了JSF服务器端状态保存)。
- 发送
javax.faces.ViewState
隐藏字段的名称 – 值对。 - 发送虚拟按下按钮的名称 – 值对。
否则,可能根本不会调用该操作。 对于残余,它与“常规”forms没有区别。 流程基本如下:
- 使用表单在页面上发送GET请求。
- 解压缩JSESSIONID cookie。
- 从响应中提取
javax.faces.ViewState
隐藏字段的值。 如果需要(确定它是否具有动态生成的名称,因此可能更改每个请求),请提取输入文件字段的名称和提交按钮。 动态生成的ID /名称可通过j_id
前缀识别。 - 准备
multipart/form-data
POST请求。 - 在该请求上设置JSESSIONID cookie(如果不为
null
)。 - 设置
javax.faces.ViewState
隐藏字段和按钮的名称 – 值对。 - 设置要上载的文件。
您可以使用任何HTTP客户端库来执行该任务。 标准的Java SE API为此提供了java.net.URLConnection
,这是非常低级别的 。 为了得到更简洁的代码,您可以使用Apache HttpClient来执行HTTP请求并管理cookie,并使用Jsoup从HTML中提取数据。
这是一个启动示例,假设页面只有一个
(否则你需要在Jsoup的CSS选择器中包含该表单的唯一标识符):
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); // ...
尝试使用HttpClient, 这是一篇我认为描述你想要的文章 ,在底部有一个标题为“使用基于HttpClient的FileUpload”的部分。
希望这可以帮助。
可能该网页只是向表单内容发送POST请求到服务器。 您可以自己从Java轻松发送此类POST请求,而无需使用该页面。 例如, 本文显示了从Java发送POST请求的示例
您需要做的是检查页面上的HTML并找出发布表单所需的参数。 它可能看起来像这样:
基于此,您可以编写一些代码来对URL进行POST请求:
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();
请记住,编写页面的人可能会进行一些检查以确保POST请求来自同一站点。 在这种情况下,您可能遇到麻烦,可能需要正确设置用户代理。
您可以尝试使用HtmlUnit 。 它提供了一个非常简单的API来模拟浏览器操作。 我已经将此方法用于类似的要求。 这很容易。 你应该试一试。