Link to home
Start Free TrialLog in
Avatar of cgray1223
cgray1223

asked on

how to handle an array of parameters in a PUT REST web service request

Hello,

I'm designing a REST web service PUT method that has an Array of query string parameters.  How is that array represented in the URL and how would I map those params to a Collection on the Java side?  I'm using RESTEasy as my jax-rs implementation.
ASKER CERTIFIED SOLUTION
Avatar of Kevin Cross
Kevin Cross
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cgray1223
cgray1223

ASKER

mwvisa1, thanks!  How would the url look?  I'm unsure how to construct it to call the service with an array of querystring params...
The URL should look like:

?name=John&name=Joe&name=Jeff

Just same parameter repeated; however, I just pulled up to do a test in Eclipse and it is acting up, so just verifying...try on your end and see as might just be my setup being just in Eclipse and not actual web server.
Let me know how your tests go please since I can't seem to get my development environment to simulate it at the moment and can't find good documentation on it for you. The above does should you though how to take it in via JAXB collections.
I don't think you can pull from the query string to populate an array using the JAX-RS spec but I could be mistaken.  The RESTEasy docs say to do the below:

@PUT
 @Path("/path/{id}/message")
 @Consumes({"application/xml","application/json"})
 public void storeMessage(Message[] message){
  message[0].getValue();
  message[1].getValue
}

The below xml would have to go in the request entity body and then a put request is sent, I guess...
<collection>  
      <message>
         <unixTime>123223333</unixTime>
         ....
       </message>    
 <collection>

Exactly, that is the technique from link in http:#a33520994 I was referring to. It is definitely a way, but could have sworn that this would work in query param also, but since I can't find documentation my only suggestion would be to test. I asked Java ZA to take a look so may have another solution or confirmation that XML is on the only way to go unless you want to parse out string yourself (i.e., send one parameter and use split() or something to that effect to bring into array).
ok, thanks for your help, please keep me updated.  I'm just looking for the best way possible.  
Here is how I might set up the array in the GET string.  There is a PHP code example to process this, below.  Not Java, but hopefully the comments will make it somewhat clear.  

http://www.laprbass.com/RAY_REST_get_last_name_array.php?key=ABC&name[]=Ray&name[]=Fred&name[]=Richard

HTH, ~Ray
<?php // RAY_REST_get_last_name_array.php
error_reporting(E_ALL);



// DEMONSTRATE HOW A RESTFUL WEB SERVICE WORKS
// CALLING EXAMPLE:
// file_get_contents('http://laprbass.com/RAY_REST_get_last_name.php?key=ABC&name[]=Ray&name[]=Brian');



// OUR DATA MODEL CONTAINS ALL THE ANSWERS
$dataModel
= array
( 'Brian'   => 'Portlock'
, 'Ray'     => 'Paseur'
, 'Richard' => 'Quadling'
)
;


// TEST THE API KEY - THE ASSUMPTION IS FAILURE
$key = FALSE;

// IF THE URL CONTAINS THE KEY
if (isset($_GET["key"])) $key = $_GET["key"];

// IF THE KEY FAILS TO MATCH OUR OUR REQUIRED 'ABC'
if ($key !== 'ABC') die('BOGUS API KEY');



// NORMALIZE THE 'name=' ARGUMENT INTO AN ARRAY
$names = array();
if (isset($_GET["name"]))
{
    if (!is_array($_GET["name"]))
    {
        // NOT AN ARRAY - MAKE IT AN ARRAY
        $names[] = $_GET["name"];
    }
    else
    {
        // ALREADY AN ARRAY - COPY IT
        $names = $_GET["name"];
    }
}
else
{
    die('NO NAME');
}

// LOOK UP THE FIRST NAMES AND FIND THE LAST NAMES
$out = '';
foreach ($names as $first_name)
{
    // IF THE NAME IS FOUND
    if (array_key_exists($first_name, $dataModel))
    {
        $out .= $first_name . ' ' . $dataModel[$first_name] . PHP_EOL;
    }
    // IF THE NAME IS NOT FOUND
    else
    {
        $out .= $first_name . ' UNKNOWN' . PHP_EOL;
    }
}

// RETURNS THE DATA STRING
die($out);

Open in new window

With RESTEasy there is a very nice annotation called @Wrapped and it will map JSON or XML requests to a JAXB Entity.  In addition to mapping to an Array, any Collection can be used (List, Set..etc).  The outer "customers" xml wrapper must match the Wrapped's name property and thats it.  

XML Request:
<?xml version="1.0" encoding="UTF-8"?>
<customers>
 <customer>
   <name>bill</name>
 </customer>
 <customer>
   <name>monica</name>
 </customer>
 </customers>

RESTEasy REST Web Service Resource:
@PUT
@Path("/user/store")
@Consumes("application/xml")
public void putCustomers(@Wrapped(name="customers") Customer[] customers)
{
    System.out.println(ccustomers.get(0).getName());
}
Glad you figured that out.  Note that it is what I linked you too here - http:#a33520994 - in case you need further reference.  I was merely hoping to find you another alternative since your question said through query string parameters.  JAXB collection, definitely a good option!

Anyway, best regards and happy coding,

Kevin
thanks, the document you referred me to was a good source, but it was missing @Wrapped.  Without that you wont be able to put/post xml to the REST resource.  Thanks for the help!
Yes they showed without the annotation for whatever reason.  Noticed they did the same with the QueryParam example.  As I said, I am glad you found that as I realized my conversations about Wrappedd were with Java ZA who didn't find example of working around this to conirm another way so I would just go with what we know works...