我怎样才能以编程方式上传文件到网站? [英] How can i programmatically upload a file to a website?

查看:90
本文介绍了我怎样才能以编程方式上传文件到网站?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须上传一个文件到服务器,只显示一个带有文件上传按钮的jsf网页(通过http)。我必须自动化一个进程(作为java独立进程完成),它会生成一个文件并将文件上传到服务器。稍后要上传文件的服务器不提供FTP或SFTP。有没有办法做到这一点?

谢谢,
Richie

解决方案当以编程方式提交JSF生成的表单时,您需要确保您考虑以下三件事: >维护HTTP会话(当然,如果网站已经打开了JSF服务器端状态保存)。
  • 发送 javax.faces.ViewState 隐藏字段。

  • 发送虚拟按钮的名称 - 值对。

  • 否则,该操作可能根本不会被调用。对于剩余它和正规形式没有什么不同。流程基本如下:


    • 使用表单在页面上发送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请求和管理cookies以及 Jsoup 从HTML中提取数据。



    假设页面只有一个< form> (否则你需要在Jsoup的CSS选择器中包含该表单的唯一标识符):

     字符串url =http:// localhost:8088 / playground / test.xhtml; 
    String viewStateName =javax.faces.ViewState;
    String submitButtonValue =上传; //上传提交按钮的值。

    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; //或者任何具体的
    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);
    // ...


    I have to upload a file to a server which only exposes a jsf web page with file upload button (over http). I have to automate a process (done as java stand alone process) which generates a file and uploads the file to the server.Sadly the server to where the file has to be uploaded does not provide a FTP or SFTP. Is there a way to do this?

    Thanks, Richie

    解决方案

    When programmatically submitting a JSF-generated form, you need to make sure that you take the following 3 things in account:

    1. Maintain the HTTP session (certainly if website has JSF server side state saving turned on).
    2. Send the name-value pair of the javax.faces.ViewState hidden field.
    3. Send the name-value pair of the button which is virtually to be pressed.

    Otherwise the action will possibly not be invoked at all. For the remnant it's not different from "regular" forms. The flow is basically as follows:

    • Send a GET request on the page with the form.
    • Extract the JSESSIONID cookie.
    • Extract the value of the javax.faces.ViewState hidden field from the response. If necessary (for sure if it has a dynamically generated name and thus possibly changes every request), extract the name of input file field and the submit buttonas well. Dynamically generated IDs/names are recognizeable by the j_id prefix.
    • Prepare a multipart/form-data POST request.
    • Set the JSESSIONID cookie (if not null) on that request.
    • Set the name-value pair of javax.faces.ViewState hidden field and the button.
    • Set the file to be uploaded.

    You can use any HTTP client library to perform the task. The standard Java SE API offers java.net.URLConnection for this, which is pretty low level. To end up with less verbose code, you could use Apache HttpClient to do the HTTP requests and manage the cookies and Jsoup to extract data from the HTML.

    Here's a kickoff example, assuming that the page has only one <form> (otherwise you need to include an unique identifier of that form in Jsoup's CSS selectors):

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

    这篇关于我怎样才能以编程方式上传文件到网站?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆