Retrieve the data sent as JSON from JavaScript, inside a servlet - json

I have a query on retrieving data sent as JSON from a JavaScript, inside a Java servlet.
Following is what I am doing...
This is the part of the code inside JavaScript making a request to a servlet
type : "POST",
url: 'getInitialData',
datatype: 'json',
data : ({items :[{ name: "John", time: "2pm" },{name: "Sam", time: "1pm" }]}),
success: function(data) {
try{
////Code to be handeled where response is recieved
}catch(e){
alert(e);
}
}
On making this request I try to retrieve the parameters sent from JavaScript in a Servlet, but while doing so I was firstly confused on how to retrieve the dat from the request
I used the following in my servlet:
NOTE : the content Type in my Servlet is set to : apllication/json
response.setContentType("application/json");
request.getParameterMap();
the above showed me the data as below, but I was not able figure out how to work and get the actual data
{items[1][name]=[Ljava.lang.String;#1930089, items[0][time]=[Ljava.lang.String;#860ba, items[1][time]=[Ljava.lang.String;#664ca, items[0][name]=[Ljava.lang.String;#1c334de}
while the following code gave me Exception of null which was expected.
request.getParametervalues("items");
Among the others i tried where request.getParameter(); request.getParameterNames(); but in vain...
Am I in a wrong direction? Please guide me!
Please let me know how to retieve these value.
Thank You for reading this long post...
Sangeet

The request parameter map is a Map<String, String[]> where the map key is the parameter name and map value are the parameter values --HTTP allows more than one value on the same name.
Given the printout of your map, the following should work:
String item0Name = request.getParameter("items[0][name]");
String item0Time = request.getParameter("items[0][time]");
String item1Name = request.getParameter("items[1][name]");
String item1Time = request.getParameter("items[1][time]");
If you want a bit more dynamics, use the following:
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String itemName = request.getParameter("items[" + i + "][name]");
String itemTime = request.getParameter("items[" + i + "][time]");
if (itemName == null) {
break;
}
// Collect name and time in some bean and add to list yourself.
}
Note that setting the response content type is irrelevant when it comes to gathering the request parameters.

Related

How to correctly display jQuery Ajax Error response text as Alert

I am trying to create an alert from an ajax callback error using:
alert(response.responseText);
However I get the whole string of error text like eg.
"{\"form_error\": {\"__all__\": [\"Data with this Doc and Date already exists.\"]}}"
which is being returned by my Django view.
My ajax function looks like:
$.ajax({
type : 'POST',
url : ...,
dateType: 'json',
data: my_data,
success : function(response){
...
},
error : function(response, status, error){
var err = response.responseText;
alert("Error: " + err);
}
});
Is there a way to only display the relevant text to the user as alert for example:
err = "Data with this Doc and Date already exists."
alert(err);
How can I display only the relevant info as alert? In my search for a possible solution I have been through numerous SO posts including ways to extract the substring of the above response text but nothing has worked.
PS. I tried to use regex on the Django view side but I could do that with multiple iteration and finally could only come up with:
{"Error": "Data with this Doc and Date already exists"} [Note the curly brackets]
What do you receive as an error response is a json string. It is a stringified json object. You have to parse it to get an acces to json properties. After this you can join all errors messages from array that contains error messages ( in this case only one, but since it is an array it can contain more then one)
const err= JSON.parse(response.responseText).form_error.__all__.join("\n");
alert(err);

How to parse a JSON response for APEX REST Service

I have written a REST class that sets a url as an endpoint to call an API. The API returns a timezone value. The url passes longitude and latitude as a parameter. The response I am getting is a complicated JSON list and I just need the Id value of the Timezone object. This is what I get as a JSON response for a lat/long value I passed:
{
"Version":"2019c",
"ReferenceUtcTimestamp":"2019-12-10T21:14:23.7869064Z",
"TimeZones":[
{
"Id":"America/Los_Angeles",
"Aliases":[
"US/Pacific",
"US/Pacific-New"
],
"Countries":[
{
"Name":"United States",
"Code":"US"
}
],
"Names":{
"ISO6391LanguageCode":"No supported language code supplied",
"Generic":"",
"Standard":"",
"Daylight":""
},
"ReferenceTime":{
"Tag":"PST",
"StandardOffset":"-08:00:00",
"DaylightSavings":"00:00:00",
"WallTime":"2019-12-10T13:14:23.7869064-08:00",
"PosixTzValidYear":2019,
"PosixTz":"PST+8PDT,M3.2.0,M11.1.0",
"Sunrise":"2019-12-10T07:42:22.383-08:00",
"Sunset":"2019-12-10T16:18:49.095-08:00"
},
"RepresentativePoint":{
"Latitude":34.05222222222222,
"Longitude":-118.24277777777777
},
"TimeTransitions":[
{
"Tag":"PST",
"StandardOffset":"-08:00:00",
"DaylightSavings":"00:00:00",
"UtcStart":"2019-11-03T09:00:00Z",
"UtcEnd":"2020-03-08T10:00:00Z"
},
{
"Tag":"PDT",
"StandardOffset":"-08:00:00",
"DaylightSavings":"01:00:00",
"UtcStart":"2020-03-08T10:00:00Z",
"UtcEnd":"2020-11-01T09:00:00Z"
},
{
"Tag":"PST",
"StandardOffset":"-08:00:00",
"DaylightSavings":"00:00:00",
"UtcStart":"2020-11-01T09:00:00Z",
"UtcEnd":"2021-03-14T10:00:00Z"
}
]
}
]
}
Here is my REST Service in APEX:
public class LPP_AccountTimeZone {
public static List<String> getTimeZone(String latitude, String longitude){
Http http = new Http();
HttpRequest req=new HttpRequest();
String url = 'https://atlas.microsoft.com/timezone/byCoordinates/json?subscription-key=XXXXXXXXXXXXXXXXXXXXXXXXXXXX&api-version=1.0&options=all&query='+latitude+','+longitude;
req.SetEndPoint(url);
req.setMethod('GET');
HttpResponse res=http.send(req);
if (res.getStatusCode() == 200) {
List<String> TimeZone = new List<String>();
TimeZoneJSON result = TimeZoneJSON.parse(res.getBody());
for(TimeZoneJSON.TimeZones t : result.timeZones){
System.debug('TimeZone is' + t.Id);
TimeZone.add(t.Id);
}
}
else{
System.debug('The status code returned was not expected: ' + res.getStatusCode() + ' ' + res.getStatus());
}
return TimeZone[0];
}
The response I got with this code (when I ran it in anonymous window) was:
TimeZone is{Aliases=(US/Pacific, US/Pacific-New), Countries=({Code=US, Name=United States}), Id=America/Los_Angeles, Names={Daylight=Pacific Daylight Time, Generic=Pacific Time, ISO6391LanguageCode=en, Standard=Pacific Standard Time}, ReferenceTime={DaylightSavings=00:00:00, PosixTz=PST+8PDT,M3.2.0,M11.1.0, PosixTzValidYear=2019, StandardOffset=-08:00:00, Sunrise=2019-12-12T07:44:13.44-08:00, Sunset=2019-12-12T16:18:47.934-08:00, Tag=PST, WallTime=2019-12-12T11:49:25.0802593-08:00}, Representativ
That is a lot of info. I just want the America/Los_Angeles part which is what Id equals (I have that bold in the response).
Another problem with this code is that it is not returning anything/is void class.
I need t return that value because a trigger is calling that method and will use this value to update a field.
Can anyone please correct my code so that it passes the correct json value and returns the value?
EDIT/UPDATE: The error I am now getting is "Variale does not exist: TimeZone (where the return statement is)
You could use JSON2APEX to easily generate an apex class from your JSON response. Just paste your full response in and click 'Create Apex'. This creates a class that represents your response so that you can easily retrieve fields from it (Keep in mind this will only really work if your response is static meaning the structure and naming stay the same). Have a look through the class that it generates and that will give you an idea of what to do. The class has a parse(String JSON) method which you can call passing in your JSON response to retrieve an instance of that class with your response values. Then it's just a matter of retrieving the fields you want as you would with any object.
Here is how getting the timezone id code would look if you take this route.
(Note: This assumes you keep the name of the class the standard 'JSON2Apex')
if (res.getStatusCode() == 200) {
JSON2Apex result = JSON2Apex.parse(res.getBody());
for(JSON2Apex.TimeZones t: result.timeZones){
System.debug('TimeZone is' + t.id);
tId.add(t);
}
}
To return a value just change void in the method signature to List<String> and return the tId list as follows return tId;

NativeScript Throwing Error Response with status: 200 for URL: null

I am using Angular4 with TypeScript version 2.2.2
My web app is running fine when I call JSON with Filters but my NativeScript app fails when I call the Filter Values as an Object but works fine when I call filter values as a string.
Error Response with status: 200 for URL: null
THIS WORKS
https://domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter=text&search=upcoming
If the filter value and search value is STRING it works whereas if they are objects as below, it does not work
THIS DOES NOT WORK
https://api.domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter={"limit":"12","skip":"0"}&search={"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}
The Code I used is below
getData(serverUrl, type, skip_limit) {
console.log(serverUrl);
let headers = this.createRequestHeader();
let token_value = localStorage.getItem('access_token')
let url;
var filter;
filter = '{"limit":"10","skip":"0"}'
url = this.apiUrl + serverUrl + '?token=' + token_value + '&filter=' + filter
return this.http.get(url, { headers: headers })
.map(res => res.json());
}
The URL as formed above for the API is fine and works fine. Yet the error comes Error Response with status: 200 for URL: null
CAN ANYONE HELP ME SOLVE THIS?
Looks like the issue is the "filter" values are of different type and from what you mentioned as what worked, your service is expecting a string and not an object/array. So it fails to send the proper response when it gets one. With an object in the URL, you may have to rewrite the service to read it as an object (parse the two attributes and get them individually)
To make it simple, you can make these two as two different variables in the URL. like below,
https://api.domainName.in/api/v1/oauth/token?limit=10&skip=0
Be more precise in whats happening in your question,
1) Log the exact URL and post it in the question. No one can guess what goes in "text" in your first URL.
2) Your URL which you mentioned as worked have "token" as part of path, but in the code, its a variable which will have a dynamic value from "token_value".
3) Post your service code. Especially the signature and input parsing part.
Got the solution:
All you have to do is encode the Filter and Search Parameters if it is an Object or Array using Typescript encodeURI()
var filter = '{"limit":"12","skip":"0"}'
var search = '{"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}'
var encoded_filter = encodeURI(filter);
var encoded_search = encodeURI(search);
url = this.apiUrl+serverUrl+'?token='+token_value+'&filter='+encoded_filter+'&search='+encoded_search

Return JSON from ASMX web service, without XML wrapper?

I need to get Json data from a C# web service.
I know there are several questions based on this, trust me I have read through quite a few but only to confuse me further.
This is what I have done :
In my web service I have included : [System.Web.Script.Services.ScriptService] for the class & [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] for the method
I have also used a JavaScriptSerializer() to convert my data to a string
I am calling this service using $.getJSON()
If I don't use that I get an Cross domain reference error.
To do this I had to setup m service to get the callback function name
so I am passing this.Context.Request["callback"] + serialized Json Data;
But in the output I get it wrapped in
< string xmlns="http://XYZ...">
The data within the tags is in the format I need
I also tried setting content type using : $.ajaxSetup({ scriptCharset: "utf-8" , contentType: "application/json; charset=utf-8"});
But still no success.
Addded later: I accepted frenchie's anwser beacuse I know it is the correct approach but I stil cud not get it to work... I just put the webservice & website in the same domain & used xml, I know it wasnt the best way, but I had spent 2 days on it & could not afford to waste more.
Use this:
var JsonString = ....;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "YourWebServiceName.asmx/yourmethodname",
data: "{'TheData':'" + JsonString + "'}",
dataType: "json",
success: function (msg) {
var data = msg.hasOwnProperty("d") ? msg.d : msg;
OnSucessCallBack(data);
},
error: function (xhr, status, error) {
alert(xhr.statusText);
}
});
function OnSuccessCallData(DataFromServer) {
// your handler for success
}
and then on the server side, in the code behind file that's auto-generated in your AppCode folder, you write something like this:
using System.Web.Services;
using System.Web.Script.Serialization;
[System.Web.Script.Services.ScriptService]
public class YourWebServiceName : System.Web.Services.WebService
{
[WebMethod]
public string yourmethodname(string TheData)
{
JavascriptSerializer YourSerializer = new JavascriptSerializer();
// custom serializer if you need one
YourSerializer.RegisterConverters(new JavascriptConverter [] { new YourCustomConverter() });
//deserialization
TheData.Deserialize(TheData);
//serialization
TheData.Serialize(TheData);
}
}
If you don't use a custom converter, the properties between the json string and the c# class definition of your server-side object must match for the deserialization to work. For the serialization, if you don't have a custom converter, the json string will include every property of your c# class. You can add [ScriptIgnore] just before a property definition in your c# class and that property will be ignored by the serializer if you don't specify a custom converter.

How to parse ASP.NET JSON Date format with GWT

ASP.NET JSON serialize DateTime to the following format "/Date(1251877601000)/". Pls, help parse this string into the java(GWT) Date object.
At this time the solution I came with is parsing with regex, extract long.. but then I cannot push long through JSNI.
function FixJsonDates(data) {
//microsoft script service perform the following to fix the dates.
//json date:\/Date(1317307437667-0400)\/"
//javasccript format required: new Date(1317307437667-0400)
//copied from micrsoft generated fiel.
var _dateRegEx = new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)(?:[a-zA-Z]|(?:\\+|-)[0-9]{4})?\\)\\\\/\\"', 'g');
var exp = data.replace(_dateRegEx, "$1new Date($2)");
return eval(exp);
}
The answer to this question is, use nuget to obtain JSON.NET then use this inside your JsonResult method:
return Json(JsonConvert.SerializeObject(/* JSON OBJECT TO SEND TO VIEW */));
inside your view simple do this in javascript:
JSON.parse(#Html.Raw(Model.data))
If it comes via a view model that is or if it is an ajax call:
var request = $.ajax({ url: "#Url.Action("SomeAjaxAction", "SomeController")", dataType: "json"});
request.done(function (data, result) { JSON.parse(data); });