How do I deserialize Drupal JSON Services strings in Android? - java

I am using Drupal Services along with the JSON Services module as a data source.
I am using the DrupalCloud library, https://github.com/skyred/DrupalCloud/wiki, and am wondering how to best process the results that I receive from a userLogin() call.
If the call itself fails we get:
{
"#error": true,
"#message": "Some message"
}
If the call succeeds but the login credentials are wrong:
{
"#error": false,
"#data": {
"#error": true,
"#message": "Some message"
}
}
If the call success and the login credentials are correct, it returns:
{
"#error": false,
"#data": {
"sessid": "foo",
"user": {
"uid": "69",
"name": "Russell Jones",
"pass": "bar",
"mail": "russell#test.net",
"roles": {
"2": "authenticated user",
"5": "Student"
},
}
}
}
How do I go about using this data meaningfully? Or rather, how do I test to see if the call worked, and if the login was successful or not.

Have you searched older posts? Like this post, from 2 hours ago:
how to convert json object into class object
or: JSON Parsing in Android
Or just search for yourself: Search: Android+Json
Should give you a good idea..

This is one way to parse the last JSON message in your question:
public void readJsonString(String jsonString) throws JSONException
{
JSONObject jsonObject = new JSONObject(jsonString);
boolean error = jsonObject.getBoolean("#error");
if (!error)
{
JSONObject data = jsonObject.getJSONObject("#data");
String sessionId = data.getString("sessid");
JSONObject user = data.getJSONObject("user");
int uid = user.getInt("uid");
String name = user.getString("name");
// you get the pattern, same way with the other fields...
}
}

Related

Adding additional field in Response Object

I am getting below response when I am calling an API.
Response postRequestResponse = ConnectionUtil.getwebTarget()
.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true)
.path("bots")
.path(ReadSkillID.readSkillId())
.path("dynamicEntities").path(dynamicEntityID)
.path("pushRequests").path(pushRequestID).path(operation)
.request()
.header("Authorization", "Bearer " + ConnectionUtil.getToken())
.get();
Below output I am getting.
{
"createdOn": "2020-08-17T12:19:13.541Z",
"updatedOn": "2020-08-17T12:19:23.421Z",
"id": "C84B058A-C8F9-41F5-A353-EC2CFE7A1BD9",
"status": "TRAINING",
"statusMessage": "Request Pushed into training, on user request"
}
I have to return this output to client with an additional field in the response. How can modify the above response and make it
{
"EntityName": "NewEntity", //New field
"createdOn": "2020-08-17T12:19:13.541Z",
"updatedOn": "2020-08-17T12:19:23.421Z",
"id": "C84B058A-C8F9-41F5-A353-EC2CFE7A1BD9",
"status": "TRAINING",
"statusMessage": "Request Pushed into training, on user request"
}
I am adding this additional field here
"EntityName": "NewEntity"
How can I do that. many things I tried but got exception.
get JSON from postRequestResponse (i have no idea what framework you are using, so you have to figer it out on your own, but the Response datatype will probably have a getResponseBody or similar method returing the JSON)
add EntityName
serialize it again to json.
class YourBean {
#Autowired
private ObjectMapper objectMapper;
public void yourMethod() {
// 1
final InputStream jsonFromResponse = ...
// 2
Map dataFromResponse = objectMapper.readValue(jsonFromResponse, Map.class);
dataFromResponse.put("EntityName", "NewEntity");
// 3
final String enrichedJson = objectMapper.writeValueAsString(dataFromResponse);
}
}
enrichedJson contains EntityName and whatever comes from the API.

Unable to parse String JSON inside post request using jersey and java

I am working on a jersey - java project where I have to get the json data in string format and parse each data separately. I am able to get the response in string using post method. When I try to use JSON lib to parse the string data class not found exception is produced. I want the returned string to be split up. Below is my json.
{
"startdate": "11/11/11",
"enddate": "12/12/12",
"operation_name": "task1",
"user_id": "user1",
"operation_key": ["KKMM-025", "SFF-025", "TTR-022"]
}
Resource method
#POST
#Path("OpertaionDetails")
#Consumes({MediaType.APPLICATION_JSON , MediaType.APPLICATION_XML})
public Response CreateOperations(String incoming_data) throws Exception
{
try
{
JSONParser parse = new JSONParser(); // class not found exceptin i have added the lib properly its working fine when it is used in main method of java.
JSONObject jobj = (JSONObject)parse.parse(incoming_data);
JSONObject Jstart_date = (JSONObject) jobj.get("startdate");
// this data to be paresed
System.out.print("incomingData"+incoming_data);
}
catch(Exception e)
{
e.printStackTrace();
}
return Response.ok(incoming_data).build();
}

autodesk forge extract geometry RVT -> OBJ results in bad request error

I am trying to extract geometry of selected objects in viewer to a separate model. For that I try following https://developer.autodesk.com/en/docs/model-derivative/v2/tutorials/extract-geometry-from-source-file/. But I get a "400 bad request" error when trying to perform post job and can't figure what could be wrong.
My code for JobPayload creation and javascript for calling are given bellow. As far as I saw other questions, people did extraction to OBJ from revit file, but according https://developer.autodesk.com/en/docs/model-derivative/v2/overview/supported-translations/ it should be possible only to do RVT to SVF. So is it possible to extract geometry from revit file or should I change it to another type? Another question is if it's possible to use svf for extraction?
private JobPayload extractGeometryToOBJ(JSONObject jsonObject) {
JobPayload job = new JobPayload();
JobPayloadInput input = new JobPayloadInput();
JSONObject inputObj = jsonObject.getJSONObject("input");
input.setUrn(inputObj.getString("urn"));
JobObjOutputPayloadAdvanced advanced = new JobObjOutputPayloadAdvanced();
advanced.setExportFileStructure(ExportFileStructureEnum.SINGLE);
JSONObject advancedFormat = (JSONObject) jsonObject.getJSONObject("output").getJSONArray("formats").get(0);
JSONObject advancedFormatInfo = advancedFormat.getJSONObject("advanced");
JSONArray objectIds = advancedFormatInfo.getJSONArray("objectIds");
List objectIdList = new ArrayList();
objectIds.forEach(e -> objectIdList.add(Integer.toString((Integer) e)));
advanced.setModelGuid(advancedFormatInfo.getString("modelGuid"));
advanced.setObjectIds(objectIdList);
JobPayloadItem formats = new JobPayloadItem();
formats.setAdvanced(advanced);
formats.setType(JobPayloadItem.TypeEnum.OBJ);
formats.setViews(Arrays.asList(JobPayloadItem.ViewsEnum._3D));
JobPayloadOutput output = new JobPayloadOutput();
output.setFormats(Arrays.asList(formats));
job.setInput(input);
job.setOutput(output);
return job;
}
function getObjects(objectIds, modelGuid) {
getForgeToken(function (access_token) {
var urn = viewerApp.myDocument.myData.urn;
jQuery.post({
url: '/api/forge/modelderivative/jobs',
contentType: 'application/json',
data: JSON.stringify({
"actionType": "extractToOBJ",
"input": {
"urn": urn
},
"output": {
"formats": [{
"type": "obj",
"advanced": {
"modelGuid": modelGuid,
"objectIds": objectIds
}
}]
}}),
success: function (res) {
console.log(res);
},
error: function (err) {
console.log(err);
}
})}, "internal")
}

proper way to handle dynamic responses by retrofit 2

let's say I've got a REST API which I could get list of books by invoking following retrofit 2 request.
public interface AllRecordsFromRequestInterface {
#GET("books/all")
Call<List<TrackInfo>> operation(#Header("Authorization") String authentication_token);
}
and API response:
[
{
"id": "1",
"title": "The Catcher in the Rye",
"author":"J. D. Salinger"
},
{
"id": "2",
"title": "The Great Gatsby",
"author":"F. Scott Fitzgerald"
}
]
I use GsonConverterFactory to convert json to a Model. here is my model class
public class Book{
private int id;
private String title;
private String author;
}
I'm using a authentication token to authorize myself to API as it can be seen in my request. some times other response are received rather than above response because of token expiration or something else. for example:
{
"status": "error",
"message": "Expired token"
}
what is the proper way to handle dynamic responses (with known structure) in retrofit 2?
you have multiple choices:
1-change your API:(this one is standard)
change it like this for every response and if the user failed with authentication leave the result null or if authentication was successful put the list in the result.
{
"status" : "error/success"
"message" : ...
"result" : ....
}
2- you can give Object type to retrofit and after the response was successful you can cast it to one of your models, using "instance of" syntax.
public interface AllRecordsFromRequestInterface {
#GET("books/all")
Call<Object> operation(#Header("Authorization") String authentication_token);
}

Dynamic JSON Data Object in GSON

I'm having a bit of trouble with GSON reading my API response JSON.
My API data returns an object with a status code, message and a data object.
The problem that I have with GSON, is that I can't figure out how to work with it properly.
For example, my API response can look like this.
{
"code": 200,
"message": "",
"data": {
"auth_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"points": 42850
}
}
OR
{
"code": 200,
"message": "",
"data": {
"items": [
{
"title" : "value"
},
{
"title" : "value"
}
]
}
}
OR others
The first response, which is a login response would be a class LoginResponse.class
public class LoginResponse {
private String auth_token;
private int points;
public String getAuthToken(){
return auth_token;
}
public int getPoints(){
return points;
}
}
and I'd use
LoginResponse response = gson.fromJson(json, LoginResponse.class);
But, how can I create a class so I can access the status code, message and the data? (which could be any of the response classes that I have)
I've looked at TypeAdapterFactory and JsonDeserializer, but couldn't get my head around it.
So, if anyone can find a SO answer that answers this question, that'd be great because I couldn't find one, or if you know how to do just this.
You could have code and message as normal, and then data could be a Map<String, Object> that you would have to interpret at runtime depending on the code or whatever you use to differentiate how the response should look.
You can solve it by doing this:
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
JsonParser parser = new JsonParser();
JsonObject rootObejct = parser.parse(json).getAsJsonObject();
JsonElement dataElement = rootObejct.get("data");
LoginResponse response = gson.fromJson(dataElement, LoginResponse.class);

Categories

Resources