HttpURLConnection sends + instead of space - java

I want to send http post request to some server and the parameters contain spaces as well as some special characters. the following is my code:
public static String HttpPost(String[] paramName, String[] paramVal)
{
try{
String parameters = null;
if ((paramName != null ) && (paramVal != null))
{
parameters = paramName[0] +"="+ paramVal[0];
for (int i = 1; i < paramName.length; i++)
{
parameters+= "&";
parameters += URLEncoder.encode(paramName[i], "US-ASCII") + "=" + URLEncoder.encode(paramVal[i], "utf-8");
}
}
//parameters = URLEncoder.encode(parameters, "utf-8");
byte[] postData = parameters.getBytes(StandardCharsets.US_ASCII);
int postDataLength = postData.length;
FolderManager fm = new FolderManager();
String urlStr = FolderManager.ApplicationUnderTestUrl();
URL url = new URL( urlStr );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
//con.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/x-www-form-urlencoded; charset=US-ASCII");
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded; charset=US-ASCII");
conn.setRequestProperty( "charset", "US-ASCII");
conn.setRequestProperty("Accept-Encoding", "identity");
conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
conn.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
wr.write( postData );
//System.out.print(postData);
}
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
return line;
}
reader.close();
return line;
}catch(Exception e)
{
return e.getMessage();
}
}
The above code sends the special characters but it sends '+' symbol where ever there is a space in the params. How do I avoid this?

I got it to work. This is what helped:
if ((paramName != null ) && (paramVal != null))
{
parameters = paramName[0] +"="+ paramVal[0];
URLEncoder.encode(parameters, "UTF-8").replace("+", "%20");
for (int i = 1; i < paramName.length; i++)
{
parameters+= "&";
parameters += URLEncoder.encode(paramName[i], "UTF-8").replace("+", "%20") + "=" + URLEncoder.encode(paramVal[i], "UTF-8").replace("+", "%20");
//parameters += paramName[i] + "=" + paramVal[i];
}
}
Hope it can help you in some way too.

Related

Microsoft graph search feature Java

I'm trying to use Microsoft Graph to make a file search. I use this entry point : https://graph.microsoft.com/beta/search/query
My application do not use a user account but a daemon with an application key (see auth method).
And i send a built object.
My java code is rather simple :
public static void main(String[] args) throws Exception{
try {
// Authentication result containing token
IAuthenticationResult result = getAccessTokenByClientCredentialGrant();
String token = result.accessToken();
SearchDocumentResponseModel documentQuery = fileGraphs.searchDocument(token, QUERYSTRING, 0, 25);
System.out.println("Find a document" + documentQuery.toString());
} catch(Exception ex){
throw ex;
}
}
private static IAuthenticationResult getAccessTokenByClientCredentialGrant() throws Exception {
ConfidentialClientApplication app = ConfidentialClientApplication.builder(
CONFIDENTIAL_CLIENT_ID,
ClientCredentialFactory.createFromSecret(CONFIDENTIAL_CLIENT_SECRET))
.authority(TENANT_SPECIFIC_AUTHORITY)
.build();
ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
Collections.singleton(GRAPH_DEFAULT_SCOPE))
.build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
return future.get();
}
The SearchDocumentResponseModel is just a set of POJO that build for me the object that i must send as a request body.
{
"requests":
[{
"entityTypes":["microsoft.graph.driveItem"],
"query":{"query_string":{"query":"any query"}},
"from":0,"size":25
}]
}
The method searchDocument is just here to build the object before i send it to the API
public SearchDocumentResponseModel searchDocument(String accessToken, String stringSearch, int from, int size) throws IOException {
SearchDocumentRequestModel searchRequest = new SearchDocumentRequestModel();
// set values here
...
URL url = new URL("https://graph.microsoft.com/beta/search/query");
return requestsBuilder.buildPostRequest(accessToken, searchRequest, url)
}
Now i want to send to server the Json and expect an answer :
public SearchDocumentResponseModel buildPostRequest(String accessToken, SearchDocumentRequestModel searchRequest, URL url) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json; utf-8");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
// write the input json in a string
String jsonInputString = new Gson().toJson(searchRequest);
try(OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
int httpResponseCode = conn.getResponseCode();
String httpResponseMessage = conn.getResponseMessage();
// reading the response
try(BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
String outputResponse = response.toString();
return new Gson().fromJson(outputResponse, SearchDocumentResponseModel.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I think i set the properties correctly. Is it coming from my code or from Microsoft Graph ? Thanks !
First of all, you should check if the access token is valid, you can send a request using postman.
If the token is valid, I think it should be the problem of your jsonInputString. The following code works fine.
URL url = new URL("https://graph.microsoft.com/beta/search/query");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "access_token" );
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json; utf-8");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String str = "";
str += "{";
str += " \"requests\": [";
str += " {";
str += " \"entityTypes\": [";
str += " \"microsoft.graph.driveItem\"";
str += " ],";
str += " \"query\": {";
str += " \"query_string\": {";
str += " \"query\": \"contoso\"";
str += " }";
str += " },";
str += " \"from\": 0,";
str += " \"size\": 25";
str += " }";
str += " ]";
str += "}";
OutputStream os = conn.getOutputStream();
byte[] input = str.getBytes("UTF-8");
os.write(input, 0, input.length);
System.out.println(conn.getResponseCode());
Update:
Query api doesn't support client credential flow.

http post request return 401 when the auth credential are correct -

I'm having this issue for posting data only, I got 401 (non-authorized) while my credential are correct! how to fix this?
ttpURLConnection urlConnection;
IgnoreSSL();
String url = null;
url = "http://" + nmap_node.getHost() + ":"+nmap_node.getPort() + "/post";
String result = null;
try {
String userpass = user_name + ":" + password; //stored in the class
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
//Connect
urlConnection = (HttpURLConnection) ((new URL(url).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", "Basic "+basicAuth);
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setConnectTimeout(10000);
urlConnection.connect();
//data
String data = datajson.toString(); //method return json to use
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(data);
writer.close();
outputStream.close();
int responseCode=urlConnection.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
//Read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
result = sb.toString();
}else {
// return new String("false : "+responseCode);
new String("false : "+responseCode);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I tried in Linux with curl command It works perfectly - I got respond 200 and printed results in the screen.

ANDROID - How to get return success from web service in android using httpurlconnection?

I've a return 0 from web services using postman if the data send successfully.
but I'm quite confused how to detect 0 message in android using HttpURLConnection
in HttpClient I'm using String response = httpclient.execute(httppost, responseHandler);
String response = httpclient.execute(httppost, responseHandler);
Log.d("MainActivity", "INSERT:" + response);
but refer to the docs
there's some code like getResponseCode() getResponseMessage() but the output is 200 for getResponseCode() and OK for getResponseMessage()
so how to get output of 0 in HttpURLConnection?
EDIT urlconnection code:
try {
JSONObject job = new JSONObject(log);
String param1 = job.getString("AuditScheduleDetailID");
String param2 = job.getString("AuditAnswerId");
String param3 = job.getString("LocalFindingID");
String param4 = job.getString("LocalMediaID");
String param5 = job.getString("Files");
String param6 = job.getString("ExtFiles");
Log.d("hasil json", param1 + param2 + param3 + param4 + param5 + param6 + " Kelar id " +
"pertama");
URL url = new URL("myurl");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
JSONObject jsonParam = new JSONObject();
jsonParam.put("AuditScheduleDetailID", param1);
jsonParam.put("AuditAnswerId", param2);
jsonParam.put("LocalFindingID", param3);
jsonParam.put("LocalMediaID", param4);
jsonParam.put("Files", param5);
jsonParam.put("ExtFiles", param6);
Log.i("JSON", jsonParam.toString());
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
//os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
os.writeBytes(jsonParam.toString());
os.flush();
os.close();
int respon = conn.getResponseCode();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("Input", String.valueOf(conn.getInputStream()));
Log.i("MSG", conn.getResponseMessage());
conn.disconnect();
} catch (JSONException | IOException e) {
e.printStackTrace();
}
This is how you need to read the data from the server using HttpUrlConnection:
try {
JSONObject job = new JSONObject(log);
String param1 = job.getString("AuditScheduleDetailID");
String param2 = job.getString("AuditAnswerId");
String param3 = job.getString("LocalFindingID");
String param4 = job.getString("LocalMediaID");
String param5 = job.getString("Files");
String param6 = job.getString("ExtFiles");
Log.d("hasil json", param1 + param2 + param3 + param4 + param5 + param6 + " Kelar id " +
"pertama");
URL url = new URL("myurl");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
JSONObject jsonParam = new JSONObject();
jsonParam.put("AuditScheduleDetailID", param1);
jsonParam.put("AuditAnswerId", param2);
jsonParam.put("LocalFindingID", param3);
jsonParam.put("LocalMediaID", param4);
jsonParam.put("Files", param5);
jsonParam.put("ExtFiles", param6);
Log.i("JSON", jsonParam.toString());
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
//os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
os.writeBytes(jsonParam.toString());
os.flush();
os.close();
InputStream is = null;
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
is = conn.getInputStream();// is is inputstream
} else {
is = conn.getErrorStream();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
String response = sb.toString();
//HERE YOU HAVE THE VALUE FROM THE SERVER
Log.d("Your Data", response);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
conn.disconnect();
} catch (JSONException | IOException e) {
e.printStackTrace();
}

HttpUrlConnection POST issue

Ok so when i try this on the browser I'am able to insert the params in the table people.
http://example.com/webservice/?value=[{
"table": "people",
"operation": "insert",
"params": [
{
"age": 8,
"name": "john",
"last_name": "johnson"
}
],
"transactionCompleted": true
}]
How can I do this with Java is my question and Where do I put the boolean value of transactionCompleted ?
public void main(String[] args) throws Exception {
int age = 30;
String name = "john";
String lastName = "johnson";
URL url = new URL("http://www.example.com/webservice/?value=[{\"table\":\"people\",\"operation\":\"insert\"}]");
Map<String,Object> params = new LinkedHashMap<>();
params.put("age", age);
params.put("name", name);
params.put("last_name", lastName);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append(',');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
for ( int c = in.read(); c != -1; c = in.read() )
System.out.print((char)c);
}
And if I want to implement this in Android, what needs to be changed.
try this code,
HttpURLConnection urlConnection = null;
try {
// create connection
URL urlToRequest = new URL(serviceUrl);
urlConnection = (HttpURLConnection) urlToRequest
.openConnection();
urlConnection.setRequestProperty("Cookie", cookie);
switch (headerType) {
case 1:
urlConnection.setRequestProperty("Accept",
"application/json;odata=verbose");
break;
default:
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
String inputdata = "";
if (properties != null) {
inputdata = properties.getProperty(Constant.ID);
}
urlConnection.setRequestProperty("Accept",
"application/json;odata=verbose");
urlConnection.setRequestProperty("Content-Length",
Integer.toString(inputdata.getBytes().length));
urlConnection.setRequestProperty("Content-Type",
"application/json;odata=verbose");
urlConnection.setRequestProperty("Auth-Token", "e1cb16d0-751c-4485-ad83-b69e848fcdf3");
urlConnection.addRequestProperty("Authorization", "Bearer " + cookie);
DataOutputStream dataOutputStream = new DataOutputStream(
urlConnection.getOutputStream());
dataOutputStream.writeBytes(inputdata);
dataOutputStream.flush();
dataOutputStream.close();
break;
}
urlConnection.setConnectTimeout(30000);
urlConnection.setReadTimeout(100000);
// handle issues
statusCode = urlConnection.getResponseCode();
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
Log.d("URL Data ", "HTTP_UNAUTHORIZED");
} else if (statusCode != HttpURLConnection.HTTP_OK) {
Log.d("URL Data ", "HTTP_NOTOK " + statusCode);
}
// create JSON object from content
InputStream in = new BufferedInputStream(
urlConnection.getInputStream());
data = getResponseText(in);
}
work for both get, and post method.
All you need to do is create a json object of your input data, and write it on Property object, like this -
JSONObject obj = new JSONObject();
obj.put("UserId","Deepak");
Property p = new Property();
p.put(Constant.ID,obj.toString();

sending chinese text in post method in java

I need to send some Chinese and Korean text to a server using a post request in java. I have tried the following but it does not work.What I receive on server side are junk or '????'.
public static String HttpPostGeneric(String URLstr, String[] paramName, String[] paramVal)
{
try{
String parameters = null;
if ((paramName != null ) && (paramVal != null))
{
parameters = paramName[0] +"="+ paramVal[0];
URLEncoder.encode(parameters, "US-ASCII").replace("+", "%20");
for (int i = 1; i < paramName.length; i++)
{
parameters+= "&";
parameters += URLEncoder.encode(paramName[i], "US-ASCII").replace("+", "%20") + "=" + URLEncoder.encode(paramVal[i], "US-ASCII").replace("+", "%20");
//parameters += paramName[i] + "=" + paramVal[i];
}
}
//parameters = URLEncoder.encode(parameters, "US-ASCII");
byte[] postData = parameters.getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length;
URL url = new URL( URLstr );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
conn.setRequestProperty("charset", "US_ASCII");
conn.setRequestProperty("Content-Length", Integer.toString( postDataLength ));
conn.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
wr.write( postData );
//System.out.print(postData);
}
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
return line;
}
reader.close();
return line;
}catch(Exception e)
{
return e.getMessage();
}
}
Using UTF-8 encoding instead of US-ASCII also does not help.
What do I do?
Using UTF-8 encoding instead of US-ASCII is not just here.
//parameters = URLEncoder.encode(parameters, "US-ASCII");
byte[] postData = parameters.getBytes(StandardCharsets.UTF_8)
but all.
the below may be work.
URLEncoder.encode(parameters, "UTF-8").replace("+", "%20");
...
parameters += URLEncoder.encode(paramName[i], "UTF-8").replace("+", "%20") + "=" + URLEncoder.encode(paramVal[i], "UTF-8").replace("+", "%20");
...
conn.setRequestProperty("charset", "UTF-8");
...
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),Charsets.UTF-8));
Hope that helped

Categories