有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java格式的表单Http POST(带文件上传)

我想做的是从java应用程序提交一个web表单。我需要填写的表格在这里:http://cando-dna-origami.org/

提交表单时,服务器会向给定的电子邮件地址发送一封确认电子邮件,目前我只是手工检查。我试着手动填写表格,邮件发送得很好。(还应注意,当表单填写错误时,页面只会刷新,不会给出任何反馈)

我以前从未对http做过任何事情,但我环顾了一会儿,想出了以下代码,它应该向服务器发送POST请求:

    String data = "name=M+V&affiliation=Company&email="
            + URLEncoder.encode("m.v@gmail.com", "UTF-8")
            + "&axialRise=0.34&helixDiameter=2.25&axialStiffness=1100&bendingStiffness=230" +
            "&torsionalStiffness=460&nickStiffness=0.01&resolution=course&jsonUpload="
            + URLEncoder.encode("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json",
            "UTF-8") + "&type=square";

    URL page = new URL("http://cando-dna-origami.org/");
    HttpURLConnection con = (HttpURLConnection) page.openConnection();

    con.setDoOutput(true);
    con.setRequestMethod("POST");
    con.connect();

    OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
    out.write(data);
    out.flush();

    System.out.println(con.getResponseCode());
    System.out.println(con.getResponseMessage());

    out.close();
    con.disconnect();

然而,当它运行时,它似乎没有做任何事情——也就是说,我没有收到任何电子邮件,尽管该程序会向系统打印“200OK”。out,这似乎表明服务器收到了一些东西,尽管我不确定它的确切含义。我认为问题可能在于文件上传,因为我不确定该数据类型是否需要不同的格式

这是使用Java发送POST请求的正确方法吗?我需要为文件上传做些不同的事情吗?谢谢


在阅读Adam的帖子后,我使用Apache HttpClient并编写了以下代码:

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("type", "square"));
    //... add more parameters

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);

    HttpPost post = new HttpPost("http://cando-dna-origami.org/");
    post.setEntity(entity);

    HttpResponse response = new DefaultHttpClient().execute(post);
    post = new HttpPost("http://cando-dna-origami.org/");

    post.setEntity(new FileEntity(new File("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json"), "text/plain; charset=\"UTF-8\""));
    HttpResponse responseTwo = new DefaultHttpClient().execute(post);

然而,它似乎仍然不起作用;同样,我也不确定上传的文件是否适合表单,所以我尝试只发送两个单独的POST请求,一个带有表单,另一个带有其他数据。我仍在寻找一种方法,将这些结合到一个请求中;有人知道这件事吗


共 (2) 个答案

  1. # 1 楼答案

    你应该明确地使用apaches HTTPClient来做那份工作!这让生活变得容易多了。下面是一个如何使用apaches HttpClient上传文件的示例

    byte[] data = outStream.toByteArray()
    HttpClient client = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost("http://localhost:8080/YourResource");
    
    ByteArrayBody byteArrayBody = new ByteArrayBody(data, "application/json", "some.json");
    MultipartEntity multipartEntity = new MultipartEntity();
    multipartEntity.addPart("upload", byteArrayBody);
    httpPost.setEntity( multipartEntity );
    
    HttpResponse response = client.execute(httpPost);
    Reader reader = new InputStreamReader(response.getEntity().getContent());
    

    如果你还有其他问题,请告诉我

  2. # 2 楼答案

    由于大多数建议的Java HTTP POST请求代码都不可操作,我决定给您提供完全可操作的代码,我相信您会发现这些代码对将来创建任何基于Java的POST请求都有帮助

    此POST请求为multipart类型,允许向服务器发送/上载文件

    多部分请求由一个主头和一个名为boundary的分隔符字符串组成,用于区分每个部分和另一部分(此分隔符将在流中以“-”(两个破折号)字符串出现,每个部分都有自己的小头,用于说明其类型和更多元数据

    我的任务是使用一些在线服务创建一个PDF文件,但所有的多部分POST示例都没有做到这一点

    我需要将一个HTML文档及其图片、JS和CSS文件打包成ZIP/TAR文件,将其上传到一个在线html2pdf转换服务,并将结果作为PDF文档作为服务的响应(流)返回给我

    我使用以下代码检查的当前服务是:Htmlpdfapi.com,但我确信,只要稍作调整,您就可以将其用于任何其他服务

    方法调用(针对该服务)看起来像: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

    这是我的代码,经过检查,100%有效:

    public void sendPOSTRequest(String url, String authData, String attachmentFilePath, String outputFilePathName)
    {
        String charset = "UTF-8";
        File binaryFile = new File(attachmentFilePath);
        String boundary = "------------------------" + Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
        String CRLF = "\r\n"; // Line separator required by multipart/form-data.
        int    responseCode = 0;
    
        try 
        {
            //Set POST general headers along with the boundary string (the seperator string of each part)
            URLConnection connection = new URL(url).openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            connection.addRequestProperty("User-Agent", "CheckpaySrv/1.0.0");
            connection.addRequestProperty("Accept", "*/*");
            connection.addRequestProperty("Authentication", authData);
    
            OutputStream output = connection.getOutputStream();
            PrintWriter writer  = new PrintWriter(new OutputStreamWriter(output, charset), true);
    
            // Send binary file - part
            // Part header
            writer.append("--" + boundary).append(CRLF);
            writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
            writer.append("Content-Type: application/octet-stream").append(CRLF);// + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
            writer.append(CRLF).flush();
    
            // File data
            Files.copy(binaryFile.toPath(), output);
            output.flush(); 
    
            // End of multipart/form-data.
            writer.append(CRLF).append("--" + boundary + "--").flush();
    
            responseCode = ((HttpURLConnection) connection).getResponseCode();
    
    
            if(responseCode !=200) //We operate only on HTTP code 200
                return;
    
            InputStream Instream = ((HttpURLConnection) connection).getInputStream();
    
            // Write PDF file 
            BufferedInputStream BISin = new BufferedInputStream(Instream);
            FileOutputStream FOSfile  = new FileOutputStream(outputFilePathName);
            BufferedOutputStream out  = new BufferedOutputStream(FOSfile);
    
            int i;
            while ((i = BISin.read()) != -1) {
                out.write(i);
            }
    
            // Cleanup
            out.flush();
            out.close();
    
    
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    
    }