I am developing an android app to create a new Quote in vTiger(ver 5.4) CRM server.
I was able to generate the new quote but the product_id and quantity that I sent for addition in quote details were not added in it. The other details are being shown in the new quote except the list of products, their quantities and pricing.
I have also studied the vTiger webservices tutorial but it was not helpful in this case.
I found an accepted answer of similar question but it is in php not in Android/JAVA.
This is how I am sending the details required to create a new quote in vTiger server.:-
try {
objectJson.put("subject", subject);
objectJson.put("account_id", accountId);
objectJson.put("bill_street", address);
objectJson.put("assigned_user_id", "19x1");
objectJson.put("conversion_rate", "1.000");
objectJson.put("currency_id", "21x1");
objectJson.put("hdnTaxType", "group");
objectJson.put("productid", productId);
objectJson.put("quantity", quantity);
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String data = null;
try {
data = URLEncoder.encode("sessionName", "UTF-8")
+ "=" + URLEncoder.encode(sessionId, "UTF-8");
data += "&" + URLEncoder.encode("element", "UTF-8") + "="
+ URLEncoder.encode(objectJson.toString(), "ISO-8859-1");
data += "&" + URLEncoder.encode("elementType", "UTF-8") + "="
+ URLEncoder.encode(moduleName, "UTF-8"); //moduleName='Quotes'
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String text = "";
BufferedReader reader=null;
// Send data
try
{
// Defined URL where to send data
URL url = new URL("http://vtiger_url/webservice.php?operation=create");
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
}
catch(Exception ex)
{
}
The above code helps me to generate the quote without product details.
After studying the above mentioned php answer, I changed the URL that I was using in my code to this:- http://vtiger_url/webservice.php?total=23000&operation=create. This helped me to add the total amount to the newly created quote but I wasn't successful to add rest of the details using this method.
The answer you have found seems to be suitable, even if it's a php solution. The problem you descirbed:
I have tried this too but unfortunately I am not able to access Inventoryproductrel table.
maybe already indicates a lack of proper authentication or missing privileges. So my suggestion is to
Find out why you can't access the table Inventoryproductrel. Try to access that table using your authentication privileges (sessionID), examine the response for any hints and try to solve the table isn't accessible issue.
Finally follow the suggestions from this answer.
Just another hint. If you can successfully access that table via you web browser, than I would sniff the request and have a look at the http parameters and their values. Based on those findings you can modify your request.
Always consider, the web browser can only do the same as you android application.
These lines were added in existing code:-
JSONArray pdoInformation = new JSONArray();
try{
// Added these lines in try block to send product details
for(int i=0; i<productIds.size(); i++) {
JSONObject obj = new JSONObject();
obj.put("productid", productIds.get(i) );
obj.put("qty", quantities.get(i));
obj.put("listprice", listprices.get(i));
pdoInformation.put(obj);
}
objectJson.put("pdoInformation", pdoInformation);
}
Here product details were needed to be sent in a JSONArray with name as "pdoInformation".
for loop is used to send multiple product details.
Here productIds, quantities and listprices are three mandatory product details stored as ArrayList.
Why don't you use the web service to create products as well? That should be supported as per the documentation.
Once you create the products and get their ids, you can create a quote object that includes these ids. The objects and their fields are not very well documented for the rest APIs, so you could use the query/describe APIs to get as much information as possible about what data needs to be supplied for creating the different objects.
From the description of the Quotes module, you would need to include item_details which will contain the product and quantity information. The exact field name and format can be obtained by the describe API as described in the web service documentation
To get a description of the vTiger objects
String modeleName = "Quotes"; //Use Products if you want a description of the Products module
String data = null;
try {
data = URLEncoder.encode("sessionName", "UTF-8")
+ "=" + URLEncoder.encode(sessionId, "UTF-8");
data += "&" + URLEncoder.encode("elementType", "UTF-8") + "="
+ URLEncoder.encode(moduleName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String text = "";
BufferedReader reader=null;
System.out.println(data);
// Send data
try
{
// Defined URL where to send data
URL url = new URL("http://vtiger_url/webservice.php?operation=describeobject");
// Send GET data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
} catch(Exception ex) {
}
Note that it's pretty much the same as what you are doing, only the url & parameters are different, and the request type is GET instead of POST
To create a product, you would follow the same procedure as you did for the quote, only the url and parameters would be different
#help as far i understand your question is how to send JsonObject with data to specified Server is that correct ? if it is the correct then i suggest you to use Volley library for networking and here are many examples that may useful to you .http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/ and http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
Just go through it. It provides easiest way to perform networking operations and also cancellation of request is also possible with this library.
Sample Code:
final String URL = "SERVER_URL";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
Using this code you can send your data to your server and at server side you can use php code to receive this jsondata and parse it.
Thanks.
Related
I'm cobbling a small android app together that I want to use for our team. All it is doing is calling to a REST API endpoint and hitting a bunch of queries. Status, alerts, some monitoring information. Pretty simple. But I have spent 3 days staring at every site on Google that explains how to make a REST API call in Java, get back the JSON, and then store it as something like a hash where I can then just reference the JSON elements by name. I wrote a desktop version in Python and I'm thinking something like where Python just parses it into a DICT. So far I have some code. I'm not even sure if it works because I'm stuck with what to do next:
protected void getJSON() {
String url = "http://192.168.8.29/api/v1/version";
try {
URL hmAPIEndPoint = new URL(url);
HttpURLConnection myConnection = (HttpURLConnection) hmAPIEndPoint.openConnection();
if (myConnection.getResponseCode() == 200) {
// Success
// Further processing here
Log.d("getJSON", "Got a 200 back from the openConnection()");
InputStream responseBody = myConnection.getInputStream();
InputStreamReader responseBodyReader = new InputStreamReader(responseBody, "UTF-8");
JsonReader jsonReader = new JsonReader(responseBodyReader);
// I need jsonReader to be something I can reference like jsonReader['version_id']
jsonReader.close();
myConnection.disconnect();
} else {
Log.e("getJSON", "Didn't register a 200 response. Actual: " + myConnection.getResponseCode());
}
} catch (MalformedURLException mfe) {
Log.e("getJSON", mfe.getStackTrace().toString());
} catch (Exception e) {
Log.e("getJSON", e.getStackTrace().toString());
}
}
From here there are like 500 sites that tell me to just parse the json line by line but that seems... stupid. Is there a way that I can get the jsonReader thing into an object like a described above?
Thanks in advance for your help.
Option 1
You can go with Retrofit network library.
It will convert all your json to POJO.
Sample tutorial
https://medium.com/#prakash_pun/retrofit-a-simple-android-tutorial-48437e4e5a23
Option 2
Try to convert inputstream to POJO with help of GSON library
Gson dependency
implementation 'com.google.code.gson:gson:2.8.5'
Sample tutorial
http://www.acuriousanimal.com/2015/10/23/reading-json-file-in-stream-mode-with-gson.html
I am trying google drive api to search parents of a folder. In search query i have to pass file id dynamically instead of hard coding. I tried below code. but I am getting file not found json response.
here its not taking fileId as value i think its consider as String
if I hardcode the value it is working.
FileList result = service.files().list().setQ("name='testfile' ").execute();
for (com.google.api.services.drive.model.File file : result.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
file.getName(), file.getId());
String fileId =file.getId();
FileList childern = service.files().list().setQ(" + \"file.getId()\" in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
This should help.
String fileid=file.getId()
service.files().list().setQ("'" + fileId + "'" + " in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
Make sure you have valid file.getId()
I know your question states java but the only sample of this working is in C#. Another issue is as far as i know PageStreamer.cs does not have an equivalent in the java client library.
I am hoping that C# and java are close enough that this might give you some ideas of how to get it working in Java. My java knowledge is quote basic but i may be able to help you debug it if you want to try to convert this.
try
{
// Initial validation.
if (service == null)
throw new ArgumentNullException("service");
// Building the initial request.
var request = service.Files.List();
// Applying optional parameters to the request.
request = (FilesResource.ListRequest)SampleHelpers.ApplyOptionalParms(request, optional);
var pageStreamer = new Google.Apis.Requests.PageStreamer<Google.Apis.Drive.v3.Data.File, FilesResource.ListRequest, Google.Apis.Drive.v3.Data.FileList, string>(
(req, token) => request.PageToken = token,
response => response.NextPageToken,
response => response.Files);
var allFiles = new Google.Apis.Drive.v3.Data.FileList();
allFiles.Files = new List<Google.Apis.Drive.v3.Data.File>();
foreach (var result in pageStreamer.Fetch(request))
{
allFiles.Files.Add(result);
}
return allFiles;
}
catch (Exception Ex)
{
throw new Exception("Request Files.List failed.", Ex);
}
I am using the following code snippet to try to create an Initiative in Rally (the values I am using for _ref I obtained while debugging).
public void createInitiative() {
CreateRequest request = null;
CreateResponse response = null;
JsonObject jo = new JsonObject();
String wsRef = "/workspace/11785043049";
String prjRef = "/project/11785043139";
jo.addProperty("Workspace", wsRef);
jo.addProperty("Project", prjRef);
jo.addProperty("Name","api_create_initiative_01");
jo.addProperty("Owner","/user/17085226946");
jo.addProperty("_ref", "/portfolioItem/initiative");
jo.addProperty("_type", "portfolioItem/initiative");
request = new CreateRequest("Initiative", jo);
try {
response = api.create(request);
JsonElement je = response.getObject();
System.out.println(je.getAsString());
} catch (IOException e) {
e.printStackTrace();
}
}
The response is :
{"CreateResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Not authorized to perform action: Invalid key"], "Warnings": ["It is no longer necessary to append \".js\" to WSAPI resources."]}}
I have no idea which "key" is invalid.
Also, not sure if I should be using "Initiative" or "PortfolioItem/Initiative" both fail
The security token needed to be append to the url as specified in the docs when you find them.
I had cannibalized code from the rallyapi test program for api setup and the security token was not appending when performing a create. Also my code snippet above had to be changed to create("PortfolioInitiative",jo) and the property "_type" was not needed
I am writing a Java lib and need to perform a request to a URL - currently using async-http-client from ning - and fetch its content. So I have a get method that returns a String
of the content of the fetched document. However, to be able to get it, I must perform a HTTP basic authentication and I'm not succeeding at this in my Java code:
public String get(String token) throws IOException {
String fetchURL = "https://www.eventick.com.br/api/v1/events/492";
try {
String encoded = URLEncoder.encode(token + ":", "UTF-8");
return this.asyncClient.prepareGet(fetchURL)
.addHeader("Authorization", "Basic " + encoded).execute().get().getResponseBody();
}
}
The code returns no error, it just doesn't fetch the URL because the authentication header is not being properly set, somehow.
With curl -u option I can easily get what I want:
curl https://www.eventick.com.br/api/v1/events/492 -u 'xxxxxxxxxxxxxxx:'
Returns:
{"events":[{"id":492,"title":"Festa da Bagaceira","venue":"Mangueirão de Paulista",
"slug":"bagaceira-fest", "start_at":"2012-07-29T16:00:00-03:00",
"links":{"tickets":[{"id":738,"name":"Normal"}]}}]}
How can this be done in Java? With the async-http-client lib? Or if you know how to do it using another way..
Any help is welcome!
You're close. You need to base 64 encode rather than URL encode. That is, you need
String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));
rather than
String encoded = URLEncoder.encode(token + ":", "UTF-8");
(Note that for the benefit of others, since I'm answering 2 years later, in my answer I'm using the more standard "user:password" whereas your question has "token:". If "token:" is what you needed, then stick with that. But maybe that was part of the problem, too?)
Here is a short, self-contained, correct example
package so17380731;
import com.ning.http.client.AsyncHttpClient;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.ws.rs.core.HttpHeaders;
public class BasicAuth {
public static void main(String... args) throws Exception {
try(AsyncHttpClient asyncClient = new AsyncHttpClient()) {
final String user = "StackOverflow";
final String password = "17380731";
final String fetchURL = "https://www.eventick.com.br/api/v1/events/492";
final String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));
final String body = asyncClient
.prepareGet(fetchURL)
.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded)
.execute()
.get()
.getResponseBody(StandardCharsets.UTF_8.name());
System.out.println(body);
}
}
}
The documentation is very sketchy, but I think that you need to use a RequestBuilder following the pattern shown in the Request javadoc:
Request r = new RequestBuilder().setUrl("url")
.setRealm((new Realm.RealmBuilder()).setPrincipal(user)
.setPassword(admin)
.setRealmName("MyRealm")
.setScheme(Realm.AuthScheme.DIGEST).build());
r.execute();
(Obviously, this example is not Basic Auth, but there are clues as to how you would do it.)
FWIW, one problem with your current code is that a Basic Auth header uses base64 encoding not URL encoding; see the RFC2617 for details.
basically, do it like this:
BoundRequestBuilder request = asyncHttpClient
.preparePost(getUrl())
.setHeader("Accept", "application/json")
.setHeader("Content-Type", "application/json")
.setRealm(org.asynchttpclient.Dsl.basicAuthRealm(getUser(), getPassword()))
// ^^^^^^^^^^^-- this is the important part
.setBody(json);
Test can be found here:
https://github.com/AsyncHttpClient/async-http-client/blob/master/client/src/test/java/org/asynchttpclient/BasicAuthTest.java
This is also another way of adding Basic Authorization,
you can use any of two the classes for your use AsyncHttpClient,HttpClient,in this case i will use AsyncHttpClient
AsyncHttpClient client=new AsyncHttpClient();
Request request = client.prepareGet("https://www.eventick.com.br/api/v1/events/492").
setHeader("Content-Type","application/json")
.setHeader("Authorization","Basic b2pAbml1LXR2LmNvbTpnMGFRNzVDUnhzQ0ZleFQ=")
.setBody(jsonObjectRepresentation.toString()).build();
after adding header part
ListenableFuture<Response> r = null;
//ListenableFuture<Integer> f= null;
try{
r = client.executeRequest(request);
System.out.println(r.get().getResponseBody());
}catch(IOException e){
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
client.close();
it may be useful for you
I want to share some information in google plus wall from my application.and I am trying for moment.insert, But getting 400 error . Can somebody help me
#Override
public JSONObject getGooglePlusAddUseractivities(Object token) {
Token accessToken = (Token) token;
OAuthService service = createOAuthServiceForGooglePlus();
OAuthRequest request = new OAuthRequest(Method.POST,"https://www.googleapis.com/plus/v1/people/me/moments/vault");
request.addQuerystringParameter("alt", "json");
service.signRequest(accessToken, request);
JSONObject object=new JSONObject();
try {
object.put("kind","plus#moment");
object.put("type","http://schemas.google.com/AddActivity");
JSONObject obj1=new JSONObject();
obj1.put("kind", "plus#itemScope");
obj1.put("url","https://plus.google.com/me");
obj1.put("description","Sign up now to claim and redeem your credits while shopping! ");
obj1.put("image","http://invite.png");
obj1.put("contentUrl", "www.abcd.com");
obj1.put("thumbnailUrl", "http://logo1_favicon.png");
object.putOpt("target", obj1);;
}catch(Exception ex) {
ex.printStackTrace();
}
request.addPayload(object.toString());
request.addHeader("Content-Type", "application/json");
System.out.println("request : "+request.getBodyContents());
Response response = request.send();
String responseBody = response.getBody();
JSONObject googleJSON = null;
try {
googleJSON = new JSONObject(responseBody);
}
catch (JSONException e) {
System.out.println("can not create JSON Object");
}
getting 400 error ?? anyone can tell me..... where am wrong ..!!`
It isn't clear from the documentation, but you can't provide both the target.url and most other target metadata. This is currently opened as bug 485 in the issue tracking system - please go there and star the issue to make sure they properly prioritize a fix.
If you remove the target.url value and add a target.id value, it should work.
(As an aside, this does not post in the user's stream, but will post an App Activity in their app moment vault. They must manually share the activity if they choose.)
At this time, it is not possible to programmatically write to a user's Stream. As a developer, you have two options:
Write an AppActivity (formerly known as a Moment), which writes information to Google, but not to a Google+ Stream. These activities are visible at plus.google.com/apps, and will be used by Google in additional ways over time.
Create an Interactive Post Share button, which a user must initiate. However, you can pre-fill both the text of the post and up to 10 intended recipients. The user can make changes if they want and then perform the actual share. You can learn more at https://developers.google.com/+/web/share/interactive or by watching this Google+ Developers Live episode: http://www.youtube.com/watch?v=U4Iw28jWtAY.