Pass array as parameter to JAX-RS resource - arrays

I have many parameters to pass to the server using JAX-RS.
Is there a way to pass or AarryList with the URL?

You have a few options here.
Option 1: A query parameter with multiple values
You can supply multiple simple values for a single query parameter. For example, your query string might look like:
PUT /path/to/my/resource?param1=value1&param1=value2&param1=value3
Here the request parameter param1 has three values, and the container will give you access to all three values as an array (See Query string structure).
Option 2: Supply complex data in the PUT body
If you need to submit complex data in a PUT request, this is typically done by supplying that content in the request body. Of course, this payload can be xml (and bound via JAXB).
Remember the point of the URI is to identify a resource (RFC 3986, 3.4), and if this array of values is data that is needed to identify a resource then the URI is a good place for this. If on the other hand this array of data forms part of the new representation that is being submitted in this PUT request, then it belongs in the request body.
Having said that, unless you really do just need an array of simple values, I'd recommend choosing the Option 2. I can't think of a good reason to use URL-encoded XML in the URL, but I'd be interested to hear more about exactly what this data is.

We can get the Query parameters and corresponding values as a Map,
#GET
#Produces(MediaType.APPLICATION_JSON)
public void test(#Context UriInfo ui) {
MultivaluedMap<String, String> map = ui.getQueryParameters();
String name = map.getFirst("name");
String age = map.getFirst("age");
System.out.println(name);
System.out.println(age);
}

Related

Camel bean binding: set parameter from variable

Given a bean method that takes a String parameter:
public void emptyDirectory(String directory) {
// code to empty give directory if it exists
}
how do i pass this parameter? The method is called here:
String to = configuration.getTo();
from(configuration.getFrom())
.to("bean:splitFileByProductType?method=emptyDirectory(to)")
....
This doesn't work as 'to' evaluates to "to", and not the value of configuration.getTo().
The documentation does not mention a case like this, so i don't know if what i'm trying to do is even possible, for example in the Simple language.
I know the value becomes accessible if i add it to the exchange header or if i hardcode it.
You can pass a value as method argument with ${body}, ${body.NAME}, ${property.NAME} and ${header.NAME}.
Examples http://camel.apache.org/bean-binding.html
So first of all you have to put your variable in Camel exchange.
To pass information from the Camel Exchange to a bean method you must not add or change anything in the route.
If you have this route (from your question). Notice that if the bean has only one method you can omit the method name.
from(whatever)
.to("bean:splitFileByProductType?methodName=emptyDirectory")
Or alternative
from(whatever)
.bean(splitFileByProductType, "emptyDirectory")
You can annotate your bean method to get the needed Exchange information automagically:
public void emptyDirectory(
#Header("directory") String directory,
#Body String body
... [other stuff to be injected] ) {
// your method impl
}
See the Camel docs for more information about this feature.
You could assign the parameter to an exchange header or property and then use simple language to pass it the bean method
String to = configuration.getTo();
from(configuration.getFrom())
.setHeader("foo", constant(to))
.to("bean:splitFileByProductType?method=emptyDirectory(${header.foo})")
...
From documentation:
The only things that can be passed to a bean are Simple tokens, a String value, a numeric value, a boolean or null.
The variable from the example cannot be expressed using Simple. What can be expressed are various properties of the exchange, most notably the exchange headers, and also some random things like literally random numbers, the current date and so on. Check the documentation for more info.
I decided to treat the whole thing as a code smell, and moved the method to a utility class which i call prior to initializing the route.

How to get CheckBoxList values in Umbraco using ContentService

Anyone knows how to get list of selected CheckBoxList values from Umbraco using ContentService?
I use contentService.GetValue("currencies")
and I get string with numbers and commas something like "154,155,156,157"
How can I get actual values?
Does anyone know how to do it using DataTypeService?
As it was mentioned above, you can use Umbraco helpers method to retrieve string value for the PreValue id.
Umbraco.GetPreValueAsString([PreValueId])
You can find more about it here: https://our.umbraco.org/documentation/reference/querying/umbracohelper/#getprevalueasstring-int-prevalueid
It's calling database directly through the DataTypeService behind the scene. It's worth to reconsider it and close it on another type of property / data type to avoid calling database on the frontend layer and just retrieve data from IPublishedContent cached model.
Read also about common pitfalls and anti-patterns in Umbraco: https://our.umbraco.org/documentation/Reference/Common-Pitfalls/
Those are prevalues.
From that given string, you have to split those and get the real value by calling one of umbraco library umbraco.library.GetPreValueAsString(123);
For example.
foreach(var item in contentService.GetValue("currencies").Split(',')) {
var realValue = umbraco.library.GetPreValueAsString(int.Parse(item);
}
You have 2 nulls because prevalues sometimes has blank values on it, like "121,56,,15,145".
You need then to modify your split code like this
foreach (var item in value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
}
StringSplitOptions.RemoveEmptyEntries will ignore empty spaces.

URL Type Hierarchy in Adobe DTM

I'm trying to create a page type hierarchy where I can use it both a page hierarchy as well as props and evars, using the page URL. In a nutshell my URL would look something like this:
http://www.domain.com/BrandHomePage/SuperCategory/ProductCategory/Product
The mindset is to take the URL and use a data element to split the URL, and then capture the values into separate data elements that could also be used in a page hierarchy.
var url = "http://www.domain.com/part1/part2/part3/part4"
var parts = url.split('/').splice(2);
console.log(parts);
var baseUrl = parts[0];
var part1 = parts[1];
var part2 = parts[2];
var part3 = parts[3];
var part4 = parts[4]
My question is, would it even be possible to capture each individual portion of the URL into separate data elements? Or is my approach overkill.
Create a Data Element
The following will create a Data Element that returns an array containing up to 4 elements, depending on how many dir levels there are in the URL.
Go to Rules > Data Elements > Create New Data Element
Name it "hier1" (no quotes).
Choose Type Custom Script and click Open Editor.
Add the following code to the code box:
return location.pathname.split('/').filter(Boolean).slice(0,4);
When you are done, Save Changes.
Populate the Hierarchy Variable
Here is an example of populating hier1 on page view.
Go to Overview > Adobe Analytics Tool Config > Pageviews & Content
Under Hierarchy, select Hierarchy1 from the dropdown (this is shown by default).
To the right of the dropdown, in the first field, add %hier1%
Leave the other 3 fields blank.
Leave Delimiter as default comma , (it doesn't matter what you put here).
Note: DTM stringifies the returned array (String(Array) or Array.toString()) from the Data Element, which is effectively the same as doing Array.join(','). This is why the above shows to only put the Data Element reference in the first field, and the Delimiter is ignored.
If your implementation uses a delimiter other than a comma, see additional notes below.
Additional Notes
Populating other Variables
You can also reference %hier1% to populate other variable fields in the Global Variables section. Note that the data element will be stringified with default comma delimiter.
Alternatively, you may consider using Dynamic Variable syntax (e.g. D=h1) as the value, to shorten the request URL. If you are using the latest AppMeasurement and Marketing Cloud Service libraries, this isn't a big deal (the libs will automatically use a POST request instead of GET request if the request URL is too long).
Using the Data Element in Custom Code Boxes
You can use _satellite.getVar('hier1') to return the data element. Note that this returns an array, e.g. ['foo','bar'], so you need to use .join() to concatenate to a single delimited string value.
Using a different Delimiter
If your implementation uses a delimiter other than a comma (,) and you use the same alternate delimiter for all your variables, you can update the Data Element as such:
return location.pathname.split('/').filter(Boolean).slice(0,4).join('[d]');
Where [d] is replaced by your delimiter. Note that this will now cause the Data Element to return a single concatenated String value instead of an Array. Using %hier1% syntax in DTM fields remains the same, but you will no longer need to use .join() in Custom Code boxes.
If your implementation uses different delimiters for different variables, implement the Data Element per the original instructions in the first section. You may use %hier1% syntax in DTM fields only if the delimiter is a comma. For all other delimiters, you will need to populate the variable in a custom code box and use a .join('[d]').
Capturing more than Four Directory Levels
Since you are no longer trying to put a value in four hierarchy fields, you may consider pushing more levels to hier1 or other variables.
In the Data Element, change the 4 in .slice(0,4); to whatever max level of dirs you want to capture. Or, if you want to capture all dir levels, remove .slice(0,4) completely.

Map as return type of #MatrixParameter

The Rest-api we are building we need some sort of filtering system to prevent too much (useless) data to be transfered to our client. The use of #MatrixParameter seems like a nice solution since this allows a readable way to filter on multiple 'levels' of the URI
However in our api we have fields our clients would like to filter on which are not defined on compile time (and can be different per client). This makes is infeasable to speficy these fields on the #matrixParam annotation.
So i was hoping there would be some way to use a Map as receiving 'bean' object
ie: when i do a GET on
https://api.example.com/rest/filtered_get;param1=value1;param2=value2/optional/continuation/of/uri/
would end up with in map containing param1,param2 as keys and value1 and value2 as values
#Get()
#Path("filtered_get")
public Response getter(#matrixParam("") HashMap<String, String/Object>parameters) {
//doStuffWiththeParameters;
}
The Service is being implemented with cxf
I think i have this figured out.
The trick is to use the PathSegment variable
usinge the code like so:
#Path("/filter{reference_to_pathParam}")
public RestEntityService<T> search(#PathParam("reference_to_pathParam") PathSegment p) {
MultiValuedMap<String,String> matrix = p.getMatrixParameters();
// doStuff with the matrix parameters
}
allows you to use unspecified matrix parameters in your URI like:
https://api.example.com/rest/../filter;field=value;field2=value2/rest/of/the/URI/
and get those fields in the matrix (map)
Note that i'm using a explicit pathsegment for this filter. This is because if i would use something like #path("/{filter}") as annotation it would interfere with other selectors using pathparameters.
Not marking this as answer yet because i dont know if there might be better/cleaner ways to do this.

Format for passing a numerically indexed array in a get request

I know that the standard method for passing named parameters in a get request, is:
?paramName=value&anotherParam=anotherValue...
In my case, I want to pass an array of parameters
However, I want to pass multiple parameters with the same meaning - an array.
In js that would be
var users = ['bob', 'sam', 'bill'];
and I want to pass the users array via get.
What would be the way to accomplish this?
You will need to serialize them into some form of string that can be re-parsed into an array.
For, example, you could use...
?param[]=a&param[]=b&param[]=c
...or something like...
?params=[a][b][b].

Resources