jax rs multidimensional array like param - multidimensional-array

I have the next object in java script:
var customObj = [];
customObj[customId] = {name:'sample',other:'other'};
customObj[customId2] = {name:'sample2',other:'other2'};
when i try to parse on a query params results in something like this:
customObj[0][name]=sample&customObj[0][other]=other&customObj[1][name]=sample2&customObj[1][other]=other2
In jax rs i have this resource:
#GET
public MyObject getSomething(#QueryParam("customObj") customObj /*Here is the problem*/){
for(ObjectOrMapOrListOrArrayList myObject:customObject){
System.out.println(myObject);//prints something like {name:'sample',other:'other'}
}
}
But i don't know how to recive the object param, i try using List> because in my object all data is a string but it doesn't work, i try using Map but i recive
incorrect parameter type error
.

You can receive the String and parse it to a JsonOnbject.
#GET
public MyObject getSomething(#QueryParam("customObj")String customObj ){
JsonReader jsonReader = Json.createReader(new StringReader(customobj));
JsonObject object = jsonReader.readObject();
jsonReader.close();
...
}
Note that this is javax.json

Related

I want to return id from a json list.But it gave a error

Error:
Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[System.Object]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'exception', line 1, position 13
MY code:
using (WebClient wc = new WebClient())
{
wc.QueryString.Add("wstoken", "49345fa96c58118326b874bxxxxxx");
wc.QueryString.Add("wsfunction", "core_user_create_users");
wc.QueryString.Add("moodlewsrestformat", "json");
wc.QueryString.Add("users[0][username]", member.uname);
wc.QueryString.Add("users[0][auth]", "manual");
wc.QueryString.Add("users[0][password]", member.password);
wc.QueryString.Add("users[0][firstname]", member.fname);
wc.QueryString.Add("users[0][lastname]", member.lname);
wc.QueryString.Add("users[0][email]", member.email);
wc.QueryString.Add("users[0][timezone]", member.timezone);
wc.QueryString.Add("users[0][description]", member.tag);//tag for group name
var response_data = wc.UploadValues(URI, "POST", wc.QueryString);
var response = Encoding.ASCII.GetString(response_data);
var k = JsonConvert.DeserializeObject<List<dynamic>>(response);
foreach (var a in k)
{
id = (a["id"]);
}
return id;
}
I want to return id from below output:
[{\"id\":38,\"username\":\"newuser30\"}]
I did this and it just worked for me:
string json = "[{\"id\":38,\"username\":\"newuser30\"}]";
dynamic [] stuff = JsonConvert.DeserializeObject<dynamic []>(json);
var id = stuff[0].id;

How to fetch local attribute value through QuerySpec in Windchill

I created a local string type attribute on a type in Windchill. I'm trying to fetch the value of that attribute using QuerySpec but it's throwing the following exception:
2019-04-16 20:53:05,092 INFO [ajp-nio-127.0.0.1-8011-exec-5]
wt.system.err - wt.query.QueryException: Attribute
"ptc_str_89typeInfoLCSProduct" is not a member of class "class
com.lcs.wc.product.LCSSKU" 2019-04-16 20:53:05,092 INFO
[ajp-nio-127.0.0.1-8011-exec-5] wt.system.err - Nested exception is:
Attribute "ptc_str_89typeInfoLCSProduct" is not a member of class
"class com.lcs.wc.produ
Following is my code:
String colorwayId = product.getFlexType().getAttribute("colorwayID")
.getColumnName();
QuerySpec qs = new QuerySpec();
int classIndex = qs.appendClassList(typeDefRef.getKey().getClass(), false);
ClassAttribute ca = new ClassAttribute(
typeDefRef.getKey().getClass(), colorwayId);
qs.appendSelect(ca, new int[] { classIndex }, false);
QueryResult qr = PersistenceHelper.manager.find(qs);
Normally ClassAttribute gets attribute name instead of column name (database column).
Your ptc_str_89typeInfoLCSProduct column is in fact typeInfoLCSProduct.ptc_str_89 like State is state.state.
To get this information, you need to use PersistableAdapter like this:
public String getAttributeColumnName(String softType, String logicalAttributeName) throws WTException {
PersistableAdapter persistableAdapter = new PersistableAdapter(softType, Locale.getDefault(), Operation.DISPLAY);
persistableAdapter.load(logicalAttributeName);
AttributeTypeSummary attributeDescriptor = persistableAdapter.getAttributeDescriptor(logicalAttributeName);
return null != attributeDescriptor ? (String) attributeDescriptor.get(AttributeTypeSummary.DESCRIPTION) : null;
}
And then use this method:
String colorwayId = getAttributeColumnName("your_softtype", "attribute_name_from_type_manager");

How to access a Dictionary passed via NSNotification, using Swift

I have code that sends a notification (where serialNumber is a String):
var dataDict = Dictionary<String, String>()
dataDict["Identity"] = serialNumber
dataDict["Direction"] = "Add"
NSNotificationCenter.defaultCenter().postNotificationName("deviceActivity", object:self, userInfo:dataDict)
And code that receives this notification:
func deviceActivity(notification: NSNotification) {
// This method is invoked when the notification is sent
// The problem is in how to access the Dictionary and pull out the entries
}
I've tried a variety of code to accomplish this, with no success:
let dict = notification.userInfo
let dict: Dictionary<String, String> = notification.userInfo
let dict: Dictionary = notification.userInfo as Dictionary
And while some of my attempts satisfy the compiler, none have yielded actual Strings when trying to access what has been extracted as a Dictionary:
let sn : String = dict["Identity"]!
let sn : String = dict.valueForKey("Identity") as String
let sn : String = dict.valueForKey("Identity")
So the question is this: How do I write Swift code to extract an object, in this case a Dictionary, that was passed via a notification, and access the component parts of that object (in this case the keys and values)?
As notification.userInfo type is AnyObject ayou must downcast it to appropriate dictionary type.
After exact type of dictionary is known you don't need to downcast values you get from it. But you may want to check if values are actually present in dictionary before using them:
// First try to cast user info to expected type
if let info = notification.userInfo as? Dictionary<String,String> {
// Check if value present before using it
if let s = info["Direction"] {
print(s)
}
else {
print("no value for key\n")
}
}
else {
print("wrong userInfo type")
}
You should use structure like [NSObject : AnyObject] and retrieve value as from NSDictionary yourLet[key]
func keyboardWillShown(notification : NSNotification){
let tmp : [NSObject : AnyObject] = notification.userInfo!
let duration : NSNumber = tmp[UIKeyboardAnimationDurationUserInfoKey] as NSNumber
let scalarDuration : Double = duration.doubleValue
}

Json adds \ charcter while returning json format

I am creating an API/web service which needs to return JSON format.
I also need to create the web service as a POST request
Sample code below, see more snippets of the source code in the end of this post.
Meta meta = new Meta();
meta.recipes = new List<Recipe>();
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize(meta);
return strJSON;
Problem:
When I try the response in a few REST consoles (list of consoles tried) and in the ASP.NET client, I get this format with an extra "d" and extra \ before each ". See return output below:
{"d":"{\"count\":\"0\",\"status\":\"500\",\"recipes\":[]}"}
When I try to remove serialization then I get the following format:
<Meta xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema"; xmlns="tempuri.org/">; <count>1</count> <status>200</status> <recipes> <Recipe> <recipeID>1</recipeID> <recipeName>Apple Pie</recipeName> <imageURL>service/it.jpg</imageURL> <rating/> </Recipe> </recipes> </Meta>
But I want it in the following format:
{"count":"0","status":"500","recipes":[]}
[WebMethod(Description = "Return all Recipe...")]
[ScriptMethod( ResponseFormat = ResponseFormat.Json)]
public Meta RecipeList(string ingredientId, string cuisineId, string dishTypeId, string courseId)
This still returns XML even though I return meta object and don't add serialization
Questions:
I thought the correct JSON format should be WITHOUT this "d" and the . Is this true or is the correct JSON format of the output actually WITH the "d" and the \?
If it should be without, then where do you suggest the correction should be made, on the server side or in the client side?
How should I correct this on the server side?
How can this be corrected on the client side?
[WebMethod(Description = "Return all Recipe...")]
[ScriptMethod( ResponseFormat = ResponseFormat.Json)]
public string RecipeList(string ingredientId, string cuisineId, string dishTypeId, string courseId,
string occasionId, string considerationId, string recipeType, string readyTime, string favouritebyUserId, string bookmarkbyUserId)
{
DataSet ds = new DataSet();
int rTime = 0;
if (readyTime == "") rTime = 0;
else rTime = Convert.ToInt32(readyTime);
ds = RecipeBLL.SearchRecipe(ingredientId, cuisineId, dishTypeId, courseId, occasionId, considerationId, recipeType, rTime);
// Create a multidimensional jagged array
string[][] JaggedArray = new string[ds.Tables[0].Rows.Count][];
int i = 0;
Meta meta = new Meta();
int count = 0;
meta.recipes = new List<Recipe>();
foreach (DataRow rs in ds.Tables[0].Rows)
{
Recipe recipe = new Recipe {
recipeID = rs["RecipeId"].ToString(),
recipeName = rs["RecipeTitle"].ToString(),
imageURL = rs["Photo"].ToString(),
rating = rs["Rating"].ToString()
};
meta.recipes.Add(recipe);
//mlist.Add(recipe);
count++;
}
if (count != 0)
meta.status = "200";
else
meta.status = "500";
meta.count = count.ToString();
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON1 = js.Serialize(meta);
return strJSON1;
}
It sounds like the problem is that you're returning a string from your code somewhere - and then it's being encoded as JSON by something else. So the string you're returning is:
{"count":"0","status":"500","recipes":[]}
... but whatever you're returning from thinks you're trying to return a string, rather than an object with a count etc.
You haven't shown any of your code, but I suspect the answer will be to just remove one explicit serialization call.

NameValueCollection to URL Query?

I know i can do this
var nv = HttpUtility.ParseQueryString(req.RawUrl);
But is there a way to convert this back to a url?
var newUrl = HttpUtility.Something("/page", nv);
Simply calling ToString() on the NameValueCollection will return the name value pairs in a name1=value1&name2=value2 querystring ready format. Note that NameValueCollection types don't actually support this and it's misleading to suggest this, but the behavior works here due to the internal type that's actually returned, as explained below.
Thanks to #mjwills for pointing out that the HttpUtility.ParseQueryString method actually returns an internal HttpValueCollection object rather than a regular NameValueCollection (despite the documentation specifying NameValueCollection). The HttpValueCollection automatically encodes the querystring when using ToString(), so there's no need to write a routine that loops through the collection and uses the UrlEncode method. The desired result is already returned.
With the result in hand, you can then append it to the URL and redirect:
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
string url = Request.Url.AbsolutePath + "?" + nameValues.ToString();
Response.Redirect(url);
Currently the only way to use a HttpValueCollection is by using the ParseQueryString method shown above (other than reflection, of course). It looks like this won't change since the Connect issue requesting this class be made public has been closed with a status of "won't fix."
As an aside, you can call the Add, Set, and Remove methods on nameValues to modify any of the querystring items before appending it. If you're interested in that see my response to another question.
string q = String.Join("&",
nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
Make an extension method that uses a couple of loops. I prefer this solution because it's readable (no linq), doesn't require System.Web.HttpUtility, and it supports duplicate keys.
public static string ToQueryString(this NameValueCollection nvc)
{
if (nvc == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string key in nvc.Keys)
{
if (string.IsNullOrWhiteSpace(key)) continue;
string[] values = nvc.GetValues(key);
if (values == null) continue;
foreach (string value in values)
{
sb.Append(sb.Length == 0 ? "?" : "&");
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
}
}
return sb.ToString();
}
Example
var queryParams = new NameValueCollection()
{
{ "order_id", "0000" },
{ "item_id", "1111" },
{ "item_id", "2222" },
{ null, "skip entry with null key" },
{ "needs escaping", "special chars ? = &" },
{ "skip entry with null value", null }
};
Console.WriteLine(queryParams.ToQueryString());
Output
?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
This should work without too much code:
NameValueCollection nameValues = HttpUtility.ParseQueryString(String.Empty);
nameValues.Add(Request.QueryString);
// modify nameValues if desired
var newUrl = "/page?" + nameValues;
The idea is to use HttpUtility.ParseQueryString to generate an empty collection of type HttpValueCollection. This class is a subclass of NameValueCollection that is marked as internal so that your code cannot easily create an instance of it.
The nice thing about HttpValueCollection is that the ToString method takes care of the encoding for you. By leveraging the NameValueCollection.Add(NameValueCollection) method, you can add the existing query string parameters to your newly created object without having to first convert the Request.QueryString collection into a url-encoded string, then parsing it back into a collection.
This technique can be exposed as an extension method as well:
public static string ToQueryString(this NameValueCollection nameValueCollection)
{
NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
httpValueCollection.Add(nameValueCollection);
return httpValueCollection.ToString();
}
Actually, you should encode the key too, not just value.
string q = String.Join("&",
nvc.AllKeys.Select(a => $"{HttpUtility.UrlEncode(a)}={HttpUtility.UrlEncode(nvc[a])}"));
Because a NameValueCollection can have multiple values for the same key, if you are concerned with the format of the querystring (since it will be returned as comma-separated values rather than "array notation") you may consider the following.
Example
var nvc = new NameValueCollection();
nvc.Add("key1", "val1");
nvc.Add("key2", "val2");
nvc.Add("empty", null);
nvc.Add("key2", "val2b");
Turn into: key1=val1&key2[]=val2&empty&key2[]=val2b rather than key1=val1&key2=val2,val2b&empty.
Code
string qs = string.Join("&",
// "loop" the keys
nvc.AllKeys.SelectMany(k => {
// "loop" the values
var values = nvc.GetValues(k);
if(values == null) return new[]{ k };
return nvc.GetValues(k).Select( (v,i) =>
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(v), i)
);
})
);
or if you don't like Linq so much...
string qs = nvc.ToQueryString(); // using...
public static class UrlExtensions {
public static string ToQueryString(this NameValueCollection nvc) {
return string.Join("&", nvc.GetUrlList());
}
public static IEnumerable<string> GetUrlList(this NameValueCollection nvc) {
foreach(var k in nvc.AllKeys) {
var values = nvc.GetValues(k);
if(values == null) { yield return k; continue; }
for(int i = 0; i < values.Length; i++) {
yield return
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(values[i]), i);
}
}
}
}
As has been pointed out in comments already, with the exception of this answer most of the other answers address the scenario (Request.QueryString is an HttpValueCollection, "not" a NameValueCollection) rather than the literal question.
Update: addressed null value issue from comment.
The short answer is to use .ToString() on the NameValueCollection and combine it with the original url.
However, I'd like to point out a few things:
You cant use HttpUtility.ParseQueryString on Request.RawUrl. The ParseQueryString() method is looking for a value like this: ?var=value&var2=value2.
If you want to get a NameValueCollection of the QueryString parameters just use Request.QueryString().
var nv = Request.QueryString;
To rebuild the URL just use nv.ToString().
string url = String.Format("{0}?{1}", Request.Path, nv.ToString());
If you are trying to parse a url string instead of using the Request object use Uri and the HttpUtility.ParseQueryString method.
Uri uri = new Uri("<THE URL>");
var nv = HttpUtility.ParseQueryString(uri.Query);
string url = String.Format("{0}?{1}", uri.AbsolutePath, nv.ToString());
I always use UriBuilder to convert an url with a querystring back to a valid and properly encoded url.
var url = "http://my-link.com?foo=bar";
var uriBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query.Add("yep", "foo&bar");
uriBuilder.Query = query.ToString();
var result = uriBuilder.ToString();
// http://my-link.com:80/?foo=bar&yep=foo%26bar
In AspNet Core 2.0 you can use QueryHelpers AddQueryString method.
As #Atchitutchuk suggested, you can use QueryHelpers.AddQueryString in ASP.NET Core:
public string FormatParameters(NameValueCollection parameters)
{
var queryString = "";
foreach (var key in parameters.AllKeys)
{
foreach (var value in parameters.GetValues(key))
{
queryString = QueryHelpers.AddQueryString(queryString, key, value);
}
};
return queryString.TrimStart('?');
}
This did the trick for me:
public ActionResult SetLanguage(string language = "fr_FR")
{
Request.UrlReferrer.TryReadQueryAs(out RouteValueDictionary parameters);
parameters["language"] = language;
return RedirectToAction("Index", parameters);
}
You can use.
var ur = new Uri("/page",UriKind.Relative);
if this nv is of type string you can append to the uri first parameter.
Like
var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);

Resources