使用Java提交HTML表单数据以从jsp应用程序检索下载

我有一个不起眼的问题。 我正在将一些Perl移植到Java,并将Perl代码中的一个方法发布到jsp应用程序并下载一个zip文件。 Perl代码的工作部分如下所示,它似乎使用get来检索文件。

$mech->get ( $url ); $mech->submit_form( fields => { upload => variable1, selectValue => variable2, }, ); 

jsp页面如下:

     Extract Features   
File:
Code: 13 14 15

我用来尝试访问它的Java代码:

 URL url = new URL(s.getUrlScheme(), s.getUrlHost(), s.getUrlFile()); String urlParameters = "upload=C:\\testFile.txt&selectValue=14"; HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/html"); connection.setRequestProperty("charset", "ISO-8859-1"); connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.length())); connection.setUseCaches(false); DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); wr.writeBytes(urlParameters); wr.flush(); wr.close(); InputStream is = connection.getInputStream(); OutputStream os = new FileOutputStream(".\\test.html"); int data; while ((data=is.read()) != -1) { os.write(data); } is.close(); os.close(); connection.disconnect(); 

首先,对于我在评论中发布的示例感到抱歉。 我以为你只想提交一些值来尝试执行一个简单的POST请求。 我错过了你也上传了一个文件 。 所以既然你也在上传一个文件(注意你不只是在这里传递文件名)这是一个mutlipart请求 (你在jsp中看到: enctype="multipart/form-data" )它还有一点点努力以编程方式做到这一点。

当您提交多部分表单时,请求如下所示:

 -----------------------------253171262814565 Content-Disposition: form-data; name="myfile"; filename="test.bin" Content-Type: application/octet-stream Test data -----------------------------253171262814565 Content-Disposition: form-data; name="submit" Submit -----------------------------253171262814565-- 

这些奇怪的字母数字被称为边界 (由浏览器随机选择),用于在提交的字段(文件或普通字段)之间进行区分。 在上面的例子中,提交的字段是:

  • 一个名为“myfile”的字段,它是表单中的 。 用户选择了名为test.bin的文件。 文件数据是单个文本行Test data
  • 按钮的"Submit"的正常字段值

下面我复制了code.java.net上的一个示例中的代码, 该示例提供了一个可以帮助您创建此类请求的类。

请修改任何硬编码的url和文件以符合您的情况。 我没有试过,但它应该让你知道如何创建一个像上面的请求。 (请注意,有两个类:一个构造请求,一个使用main()方法来测试它)

旁注:行字符\r\n的更改不依赖于系统,但它是如何构造多部分请求的一部分。 因此,无论您的系统是Windows还是Linux,都应该按原样使用它

我希望有所帮助

 package net.codejava.networking; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; /** * This utility class provides an abstraction layer for sending multipart HTTP * POST requests to a web server. * @author www.codejava.net * */ public class MultipartUtility { private final String boundary; private static final String LINE_FEED = "\r\n"; private HttpURLConnection httpConn; private String charset; private OutputStream outputStream; private PrintWriter writer; /** * This constructor initializes a new HTTP POST request with content type * is set to multipart/form-data * @param requestURL * @param charset * @throws IOException */ public MultipartUtility(String requestURL, String charset) throws IOException { this.charset = charset; // creates a unique boundary based on time stamp boundary = "===" + System.currentTimeMillis() + "==="; URL url = new URL(requestURL); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setDoOutput(true); // indicates POST method httpConn.setDoInput(true); httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); outputStream = httpConn.getOutputStream(); writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true); } /** * Adds a form field to the request * @param name field name * @param value field value */ public void addFormField(String name, String value) { writer.append("--" + boundary).append(LINE_FEED); writer.append("Content-Disposition: form-data; name=\"" + name + "\"") .append(LINE_FEED); writer.append("Content-Type: text/plain; charset=" + charset).append( LINE_FEED); writer.append(LINE_FEED); writer.append(value).append(LINE_FEED); writer.flush(); } /** * Adds a upload file section to the request * @param fieldName name attribute in  * @param uploadFile a File to be uploaded * @throws IOException */ public void addFilePart(String fieldName, File uploadFile) throws IOException { String fileName = uploadFile.getName(); writer.append("--" + boundary).append(LINE_FEED); writer.append( "Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"") .append(LINE_FEED); writer.append( "Content-Type: " + URLConnection.guessContentTypeFromName(fileName)) .append(LINE_FEED); writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); writer.append(LINE_FEED); writer.flush(); FileInputStream inputStream = new FileInputStream(uploadFile); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); inputStream.close(); writer.append(LINE_FEED); writer.flush(); } /** * Completes the request and receives response from the server. * @return a list of Strings as response in case the server returned * status OK, otherwise an exception is thrown. * @throws IOException */ public List finish() throws IOException { List response = new ArrayList(); writer.append(LINE_FEED).flush(); writer.append("--" + boundary + "--").append(LINE_FEED); writer.close(); // checks server's status code first int status = httpConn.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { BufferedReader reader = new BufferedReader(new InputStreamReader( httpConn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { response.add(line); } reader.close(); httpConn.disconnect(); } else { throw new IOException("Server returned non-OK status: " + status); } return response; } } //--------------------------------------------------------- package net.codejava.networking; import java.io.File; import java.io.IOException; import java.util.List; /** * This program demonstrates a usage of the MultipartUtility class. * @author www.codejava.net * */ public class MultipartFileUploader { public static void main(String[] args) { String charset = "UTF-8"; File uploadFile1 = new File("e:/Test/PIC1.JPG"); File uploadFile2 = new File("e:/Test/PIC2.JPG"); String requestURL = "http://localhost:8080/FileUploadSpringMVC/uploadFile.do"; try { MultipartUtility multipart = new MultipartUtility(requestURL, charset); multipart.addFormField("description", "Cool pix"); multipart.addFilePart("fileUpload", uploadFile1); multipart.addFilePart("fileUpload", uploadFile2); List response = multipart.finish(); System.out.println("SERVER REPLIED:"); for (String line : response) { System.out.println(line); } } catch (IOException ex) { System.out.println("ERROR: " + ex.getMessage()); ex.printStackTrace(); } } }