HTTP/1.1 400 Bad Request in java HTTP post - java

I am trying to post xml data to API using HTTP post method with credentials but a getting HTTP/1.1 400 Bad Request error .. Can anyone pl help me out ....
Here is my sample code:
BufferedReader br = new BufferedReader(new FileReader(new File("Data.xml")));
StringBuilder sb = new StringBuilder();
while((line=br.readLine())!= null){
sb.append(line.trim());
}
System.out.println("xml: "+sb);
params=sb.toString();
HttpPost request = new HttpPost("*****************url***************");
String urlaparam=URLEncoder.encode("importFormatCode:1&data:"+params,"UTF-8");
String userCredentials = "****:******";
byte[] auth = Base64.encodeBase64(userCredentials.getBytes());
StringEntity entity=new StringEntity(urlaparam);
request.addHeader("Content-type","application/x-www-form-urlencoded");
request.addHeader("Accept", "application/xml");
request.addHeader("Accept-Language", "en-US,en;q=0.5");
request.addHeader("Authorization", "Basic " + new String(auth));
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);
System.out.println(response.getStatusLine());
System.out.println(request);
}
catch(Exception e)
{
}

First of all, your form parameters are not encoded correctly. You are using colon (:) to separate keys from their values, but instead, the equal sign (=) must be used:
Wrong: "importFormatCode:1&data:" + params
Correct: "importFormatCode=1&data=" + params
(See also W3C.org - Forms in HTML Documents - application/x-www-form-urlencoded)
Apart from that, you must not URL-encode the entire string but only the keys and the values. Otherwise you'll also encode the separator characters = and &!
The easiest way is to use the existing utility class org.apache.http.client.utils.URLEncodedUtils (assuming that you're using Apache HTTP Components):
String xmlData = // your xml data from somewhere
List<NameValuePair> params = Arrays.asList(
new BasicNameValuePair("importFormatCode", "1"),
new BasicNameValuePair("data", xmlData)
);
String body = URLEncodedUtils.format(params, encoding); // use encoding of request
StringEntity entity = new StringEntity(body);
// rest of your code

Related

SharePoint REST API with Java - Authentication error

I have the following Java code to send a POST request to SharePoint REST API to create a list and it returns the following authentication errors:
CloseableHttpClient httpClient = null;
try {
String user = xxx;
String password = xxx;
String domain = xxx;
String workstation = "";
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(AuthScope.ANY),
new NTCredentials(user, password, workstation, domain));
httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
String digestQueryURL = "http://my_sharepoint_site/_api/contextinfo";
HttpPost httpPost = new HttpPost(digestQueryURL);
httpPost.addHeader("Accept", "application/json;odata=verbose");
CloseableHttpResponse response = httpClient.execute(httpPost);
byte[] content = EntityUtils.toByteArray(response.getEntity());
String jsonString = new String(content, "UTF-8");
ObjectMapper mapper = new ObjectMapper();
JsonNode j = mapper.readTree(jsonString);
String formDigestValue = j.get("d").get("GetContextWebInformation").get("FormDigestValue").toString();
response.close();
// now try to create the list
String url = "http://my_sharepoint_site/_api/web/lists";
HttpPost httpPost2 = new HttpPost(url);
httpPost2.addHeader("X-RequestDigest", getFormDigest(httpClient));
httpPost2.addHeader("Accept", "application/json;odata=verbose");
httpPost2.addHeader("Content-Type", "application/json;odata=verbose");
String body = "{ '__metadata': { 'type': 'SP.List' }, 'AllowContentTypes': true, 'BaseTemplate': 100, 'ContentTypesEnabled': true, 'Description': 'My list description', 'Title': 'Test' }";
StringEntity se = new StringEntity(body);
httpPost2.setEntity(se);
CloseableHttpResponse response2 = httpClient.execute(httpPost2);
StringBuilder result = new StringBuilder();
System.out.println(response2.getStatusLine().toString());
BufferedReader br = new BufferedReader(new InputStreamReader(response2.getEntity().getContent()));
String output;
while ((output = br.readLine()) != null) {
result.append(output);
}
System.out.println(result.toString());
} catch (Exception e) {
}
Console output
HTTP/1.1 403 FORBIDDEN
{"error":{"code":"-2130575251, System.Runtime.InteropServices.COMException","message":{"lang":"en-US","value":"The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again."}}}
I can use very similar code to send GET requests to the REST API to retrieve all lists, retrieve list items, perform all these read operations. However this does not work for POST requests. Am I doing something wrong? The credentials provided are for an account that has full control over the entire site collection, so we can rule out permission errors.
Alright, the problem is really very simple. This line:
String formDigestValue = j.get("d").get("GetContextWebInformation").get("FormDigestValue").toString();
Returns the formDigestValue with quotation marks enclosing it. Using asText() instead of toString() helped.

Microsoft Cognitive Services - Bing Speech to Text with JAVA - curl to http request

i want to code a java http request for posting audio file (wav) for speech to text transformation.
I´m quite new to http requests, and could not find any useful hints how to achieve that.
In https://www.microsoft.com/cognitive-services/en-us/Speech-api/documentation/GetStarted/GetStarted-cURL I was able to get token (Step 1 in url), but now I am struggeling with step 2.
Can someone help or even provide java code for step 2 (post wav file to cognitive services).
CURL Request given:
curl -v -X POST "https://speech.platform.bing.com/recognize? scenarios=smd&appid=D4D52672-91D7-4C74-8AD8- 42B1D98141A5&locale=your_locale&device.os=your_device_os&version=3.0&format=json&instanceid=your_instance_id&requestid=your_request_id" -H 'Authorization: Bearer your_access_token' -H 'Content-type: audio/wav; codec="audio/pcm"; samplerate=16000' --data-binary #your_wave_file
My Java HTTP code so far (Using Apache):
HttpClient client = HttpClientBuilder.create().build();
String url = "https://speech.platform.bing.com/recognize";
String appId = "D4D52672-91D7-4C74-8AD8-42B1D98141A5"; //Always use this. See Docu
String token = "12345"; // received from step 1 (see MS documentation)
String locale = "de-DE";
String deviceOS = "Windows";
String version = "3.0";
String format = "json";
String instanceid = UUID.randomUUID().toString();
String scenarios = "smd";
// setting up post parameters
Map<String, String> postParameters = new HashMap<>();
postParameters.put("scenarios", scenarios);
postParameters.put("appid", appId);
postParameters.put("locale", locale);
postParameters.put("device.os", deviceOS);
postParameters.put("format", format);
postParameters.put("instanceid", instanceid);
postParameters.put("requestid", instanceid);
postParameters.put("version", version);
// setting up HttpPost
HttpPost httpPost = new HttpPost(url);
// PARAMETERS
List<NameValuePair> qparams = new ArrayList<>();
for (Map.Entry<String, String> s : postParameters.entrySet()) {
qparams.add(new BasicNameValuePair(s.getKey(), s.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(qparams));
// HEADERS
String wavFile = "C:\\Folder\\AudioData.wav";
Map<String, String> postHeaders = new HashMap<>();
postHeaders.put("Authorization", "Bearer " + token);
postHeaders.put("Content-Type", "audio/wav; codec=\"audio/pcm\"; samplerate=16000");
for (Map.Entry<String, String> entry : postHeaders.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
// WAV FILE
File file = new File(wavFile);
FileBody bin = new FileBody(file, ContentType.DEFAULT_BINARY);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("bin", bin);
HttpEntity reqEntity = builder.build();
httpPost.setEntity(reqEntity);
// RESPONSE
HttpResponse response = client.execute(httpPost);
int responseCode = response.getStatusLine().getStatusCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuilder result = new StringBuilder();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
My Response code is 200, but my response.getEntity().getContent() is empty. I expect a JSON there.
btw: if i fire this up with curl (with set parameters of course) it works, and I get a JSON back with recognized speech to text.
Can you help me with that?
Nycon

HttpResponse with special characters

I have written a REST client for this endpoint:
textmap.com/ethnicity_api/api
However, while passing it a name string like jennífer garcía in the POST params, and setting encoding to UTF-8, the response that I get is not the same string. How to get the same name in the response object?
Below is how I set the request and the response thatI get:
httpClient = HttpClients.createDefault();
httpPost = new HttpPost(baseurl);
StringEntity input = new StringEntity(inputJSON, StandardCharsets.UTF_8);
input.setContentType("application/json");
//input.setContentType("application/json; charset=UTF-8");
httpPost.setEntity(input);
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
output = org.apache.commons.io.IOUtils.toString(br);
System.out.println(output);
Value of the name in output is : jenn�fer garc�a
This is a completely different charset from what I had sent in the request. How can I get the same charset as I had sent in request?
Secondly, I want the same code to work in both Java-6 and Java-7. The above code is using Java-7 only. How can I make the code work for both these versions?
I think the BufferedReader is breaking the UTF8 encoding, so this is actually pretty unrelated to HTTP. On a side note, the br may not be needed at all.

how to insert cypher statement in http post request

I have just started with neo4J and wanted to try the transactional cypher endpoint. I have my neo4J server running on localhost:7474/ and have inserted the movie data.
As stated in the documentation, I have to do a post request and include some parameters. Unfortunately I don't know how I have to include my query in the POST request. As far as I have understood it, I have to pass a JSON String.
private static String sendPost() throws Exception {
String url = "http://localhost:7474/db/data/transaction";
String statement ="[ { \"statement\" : \"MATCH (n:Person) RETURN n.name, n.born\"} ]";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("Accept", "application/json; charset=UTF-8"));
urlParameters.add(new BasicNameValuePair("Content-Type", "application/json"));
urlParameters.add(new BasicNameValuePair("statements", statement));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
StringBuilder builder = new StringBuilder();
builder.append("\nSending 'POST' request to URL : " + url+"<br>");
builder.append("Post parameters : " + post.getEntity()+"<br>");
builder.append("Response Code : " + response.getStatusLine().getStatusCode()+"<br>");
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
result.append("<p>");
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line+"\n");
}
result.append("</p>");
return builder.toString();
}
When I execute the code, I get the following output:
Sending 'POST' request to URL : http://localhost:7474/db/data/transaction
Post parameters : org.apache.http.client.entity.UrlEncodedFormEntity#76adb5f6
Response Code : 415
Can anyone help me on how I have to include my query in the POST request?
http://docs.neo4j.org/chunked/stable/rest-api-transactional.html
Looking at that, you can see the body of your POST request isn't what the server is expecting, i.e. you should be sending an entire JSON document, and not a k/v pair w/ "statements" as a key and your JSON Cypher query as the value. Remember you're sending JSON here, and not a URLEncoded body.
Also, it looks like you're setting the "Accept" and "Content-Type" k/v pairs as part of the POST body when they should, in fact, be part of the headers.
Also also, consider using the Cypher endpoint: http://docs.neo4j.org/chunked/stable/rest-api-cypher.html
HTH

Java: Adding raw data to payload Httpost request

I intend to send a simple http post request with a large string in the Payload.
So far I have the following.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("address location");
String cred = "un:pw";
byte[] authEncBytes = Base64.encodeBase64(cred.getBytes());
String authStringEnc = new String(authEncBytes);
httppost.setHeader("Authorization","Basic " + authStringEnc);
However, I do not know how to attach a simple RAW string into the payload. The only examples I can find are name value pairs into the Entity but this is not what I want.
Any assistance?
It depends on the concrete HTTP-API you're using:
Commons HttpClient (old - end of life)
Since HttpClient 3.0 you can specify a RequestEntity for your PostMethod:
httpPost.setRequestEntity(new StringRequestEntity(stringData));
Implementations of RequestEntity for binary data are ByteArrayRequestEntity for byte[], FileRequestEntity which reads the data from a file (since 3.1) and InputStreamRequestEntity, which can read from any input stream.
Before 3.0 you can directly set a String or an InputStream, e.g. a ByteArrayInputStream, as request body:
httpPost.setRequestBody(stringData);
or
httpPost.setRequestBody(new ByteArrayInputStream(byteArray));
This methods are deprecated now.
HTTP components (new)
If you use the newer HTTP components API, the method, class and interface names changed a little bit, but the concept is the same:
httpPost.setEntity(new StringEntity(stringData));
Other Entity implementations: ByteArrayEntity, InputStreamEntity, FileEntity, ...
i was making a common mistake sequence of json object was wrong. for example i was sending it like first_name,email..etc..where as correct sequence was email,first_name
my code
boolean result = false;
HttpClient hc = new DefaultHttpClient();
String message;
HttpPost p = new HttpPost(url);
JSONObject object = new JSONObject();
try {
object.put("updates", updates);
object.put("mobile", mobile);
object.put("last_name", lastname);
object.put("first_name", firstname);
object.put("email", email);
} catch (Exception ex) {
}
try {
message = object.toString();
p.setEntity(new StringEntity(message, "UTF8"));
p.setHeader("Content-type", "application/json");
HttpResponse resp = hc.execute(p);
if (resp != null) {
if (resp.getStatusLine().getStatusCode() == 204)
result = true;
}
Log.d("Status line", "" + resp.getStatusLine().getStatusCode());
} catch (Exception e) {
e.printStackTrace();
}
return result;
Answer

Categories

Resources