Как я могу программно загрузить файл на сайт? - PullRequest
3 голосов
/ 24 декабря 2011

Мне нужно загрузить файл на сервер, который предоставляет только веб-страницу jsf с кнопкой загрузки файла (через http).Я должен автоматизировать процесс (выполняемый как отдельный процесс java), который генерирует файл и загружает файл на сервер.Есть ли способ сделать это?

Спасибо, Ричи

Ответы [ 5 ]

7 голосов
/ 24 декабря 2011

При программной отправке формы, сгенерированной JSF, необходимо убедиться, что вы учли следующие 3 вещи:

  1. Поддерживать сеанс HTTP (конечно, если на веб-сайте включено сохранение состояния на стороне сервера JSF).
  2. Отправьте пару имя-значение скрытого поля javax.faces.ViewState.
  3. Отправьте пару «имя-значение» кнопки, которая должна быть фактически нажата.

В противном случае действие, возможно, вообще не будет запущено. Для остатка он ничем не отличается от «обычных» форм. Поток в основном выглядит следующим образом:

  • Отправьте запрос GET на страницу с формой.
  • Извлеките файл cookie JSESSIONID.
  • Извлечь значение скрытого поля javax.faces.ViewState из ответа. При необходимости (наверняка, если оно имеет динамически генерируемое имя и, следовательно, возможно, меняет каждый запрос), хорошо извлеките имя поля входного файла и кнопку отправки. Динамически генерируемые идентификаторы / имена распознаются по префиксу j_id.
  • Подготовить multipart/form-data POST-запрос.
  • Установите cookie-файл JSESSIONID (если не null) для этого запроса.
  • Установите пару имя-значение для скрытого поля javax.faces.ViewState и кнопки.
  • Установить файл для загрузки.

Вы можете использовать любую клиентскую библиотеку HTTP для выполнения задачи. Стандартный Java SE API предлагает java.net.URLConnection для этого, что является довольно низким уровнем . Чтобы получить менее подробный код, вы можете использовать Apache HttpClient для выполнения HTTP-запросов и управления файлами cookie и Jsoup для извлечения данных из HTML.

Вот пример запуска, предполагая, что на странице есть только один <form> (в противном случае вам необходимо включить уникальный идентификатор этой формы в селекторы CSS Jsoup):

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);
// ...
1 голос
/ 24 декабря 2011

Попробуйте использовать HttpClient, вот статья , которая, я думаю, описывает то, что вы хотите, внизу есть раздел под названием «Использование FileUpload на основе HttpClient».

Надеюсь, это поможет.

0 голосов
/ 24 декабря 2011

Вы можете попробовать использовать HtmlUnit для этого.Он предоставляет очень простой API для имитации действий браузера.Я уже использовал этот подход для аналогичных требований.Это очень просто.Вы должны попробовать.

0 голосов
/ 24 декабря 2011

Что вам нужно сделать, это изучить HTML-код на странице и выяснить, какие параметры необходимы для публикации формы. Вероятно, это будет выглядеть примерно так:

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

Исходя из этого, вы можете написать некоторый код для выполнения запроса POST к URL:

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 пришел с того же сайта. В этом случае у вас могут быть проблемы, и вам может потребоваться правильно настроить пользовательский агент.

0 голосов
/ 24 декабря 2011

Вероятно, эта веб-страница просто отправляет POST-запрос на сервер с содержимым формы. Вы можете легко отправить такой запрос POST самостоятельно с Java, не используя эту страницу. Например эта статья показывает пример отправки запросов POST из Java

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...