There is an XML file match.xml, through curl it is easy to send a POST and add to the database.

curl -F "xml=@match.xml" web_url 

Standard Java POST implementation returns POST Response Code :: 400 Bad Request to me

 public static void sendPOST(String data) throws IOException { URL obj = new URL(FinalConstants.BETRADAR_UPLOAD); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("User-Agent", USER_AGENT); // For POST only - START con.setDoOutput(true); OutputStream os = con.getOutputStream(); os.write(data.getBytes()); os.flush(); os.close(); // For POST only - END int responseCode = con.getResponseCode(); System.out.println("POST Response Code :: " + responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { //success BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // print result System.out.println(response.toString()); } else { System.out.println("POST request not worked"); } } 

and with such settings returns the same error

  httpURLConnection.setReadTimeout(10000); httpURLConnection.setConnectTimeout(15000); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Content-Type", "text/xml"); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); 

Tell me how curl -F works? How do I send the data correctly?

UPD

I tried several options with HttpClient and they all give the following

HttpResponseProxy {HTTP / 1.1 400 Bad Request [Server: nginx, Date: Thu, 09 Feb 2017 20:07:18 GMT, Content-Type: application / octet-stream, Content-Length: 0, Connection: keep-alive]}

Option 1

  HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(FinalConstants.UPLOAD); HttpEntity entity = new ByteArrayEntity(data.getBytes("UTF-8"), ContentType.TEXT_XML); post.setEntity(entity); HttpResponse response = client.execute(post); String result = EntityUtils.toString(response.getEntity()); 

Option 2

 InputStream in ; StringEntity entity = new StringEntity(data, ContentType.create( "text/xml", Consts.UTF_8)); entity.setChunked(true); HttpPost httppost = new HttpPost( FinalConstants.UPLOAD); httppost.setEntity(entity); HttpClient client = HttpClients.createDefault(); HttpResponse response = client.execute(httppost); System.out.println(response.toString()); in=response.getEntity().getContent(); String body = IOUtils.toString(in); System.out.println(body); 

Also option using file

 builder.addBinaryBody( "file", new FileInputStream(f), ContentType.APPLICATION_OCTET_STREAM, // Π’Π°ΠΊΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ f.getName() ); 

All the same, I would like to send a string, not a file.

UPD2

 public static void sendPOST(File file) throws IOException { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { final HttpPost uploadFile = new HttpPost(FinalConstants.UPLOAD); final HttpEntity entity = MultipartEntityBuilder .create() .addBinaryBody("xml", file).build(); uploadFile.setEntity(entity); final HttpResponse response = httpClient.execute(uploadFile); System.out.println(EntityUtils.toString(response.getEntity())); } } java.lang.NoSuchMethodError: org.apache.http.entity.ContentType.create(Ljava/lang/String;[Lorg/apache/http/NameValuePair;)Lorg/apache/http/entity/ContentType; at org.apache.http.entity.mime.MultipartEntityBuilder.buildEntity(MultipartEntityBuilder.java:219) at org.apache.http.entity.mime.MultipartEntityBuilder.build(MultipartEntityBuilder.java:240) 
  • And you do not want to use any library for it? - Mikhail Vaysman
  • Like what? - Senior Pomidor
  • for example, HttpClient - Mikhail Vaysman
  • @MikhailVaysman did not help. I'm doing something wrong - Senior Pomidor

1 answer 1

curl -F emulates sending HTTP forms, "xml=@match.xml" - attach a file with the specified name.
For such an HTTP request (with an attached file), the Content-Type must be multipart/form-data , and one of the parts of such a request (part) must have the name xml (for your example) and contain a file with the appropriate Content-Type.
Honestly, as already suggested in the comments to the question, it is easier to use the Apache HttpClient library.
There are a lot of examples of how to send multipart/form-data using HttpClient, here’s the first one from Google: https://stackoverflow.com/questions/1378920/how-can-i-make-a-multipart-form-data-post-request -using-java

Edit: This code gives the same query as curl -F "xml=@match.xml" web_url

  try (CloseableHttpClient httpClient = HttpClients.createDefault()) { final HttpPost uploadFile = new HttpPost("web_url"); final HttpEntity entity = MultipartEntityBuilder.create().addBinaryBody("xml", new File("match.xml")).build(); uploadFile.setEntity(entity); final HttpResponse response = httpClient.execute(uploadFile); System.out.println(EntityUtils.toString(response.getEntity())); } 

You must also add the following dependencies (Maven):

 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.3</version> </dependency> 
  • did not help. I'm doing something wrong - Senior Pomidor
  • and on the server side there is an opportunity to see the logs? as an option - put fiddler and see what kind of query really leaves when using curl, and from this dance. Lay out the code if there is time tomorrow - see what could be wrong - Sergi
  • code updated in the question. no access to the logs - Senior Pomidor
  • you send the wrong request, you need multipart / form-data - look again at the example in stackoverflow.com/a/1379002/2269692 You need to use MultipartEntityBuilder builder = MultipartEntityBuilder.create(); and then builder.addBinaryBody - Sergi
  • This is about the request sent by curl when the -F flag is used and "xml=@README" : jpst.it/TaLb - Sergi