Reputation: 919
Aloha.
I have a Restlet server application with a @Get method that is supposed to be returning Object[], but the client receives an Object[] with elements of type LinkedHashMap. Each of the received array's elements correspond to the respective elements of the objects that the server was supposed to send.
Here is the relevant part of my resource (interface) file:
@Get
public Object[] retrieve() ;
Here is the relevant portion of my server resource file:
public Object[] retrieve()
{
User newUser = new User() ;
newUser.firstName = "John" ;
newUser.lastName = "Doe" ;
Object[] objectArray = (Object[]) Array.newInstance( User.class, 1 ) ;
objectArray[0] = newUser ;
return objectArray ;
}
Here is the relevant portion of my client:
public static void main( String[] args ) throws Exception
{
Object[] arrayOfObjects = (Object[]) clientResource.retrieve() ; // array of LinkedHashMap elements
}
I assume that obtaining the result that I desire to obtain is easily done, but I am still very new to the Restlet framework. Thus, can someone tell me what I am doing wrong and show me an example of how to correctly send an array of (JSON encoded) objects from the server?
Thanks, in advance.
Take care,
Darwin
==================================================================================
Per StaxMan's comment (below), I also tried returning a generic List, but this just resulted in an ArrayList of LinkedHashMap elements, not an ArrayList of the desired type of elements.
Here is the relevant part of my resource (interface) file:
@Get
public <T> List<T> retrieve() ;
Here is the relevant portion of my server resource file:
public <T> List<T> retrieve()
{
List<T> list = ... ;
return list ;
}
Here is the relevant portion of my client:
// the following does not work, since the returned ArrayList's
// elements are not User objects but LinkedHashMap objects:
User[] users = (User[]) ((ArrayList<User>)clientResource.<User>retrieve()).toArray( (User[])Array.newInstance(User.class,0) ) ;
Can anyone tell me how to obtain an Array or List or ArrayList of the objects that I want from the server, while still maintaining the generic (or even pseudo generic) nature of the server?
Thanks, in advance.
Upvotes: 0
Views: 936
Reputation: 1352
restlet framework DO NOT support return the parameterized type because it only support Class<?> as parameter
restlet framework use org.restlet.service.ConverterService
public <T> T toObject(Representation source, Class<T> target, Resource resource) throws IOException {
................
}
but java Class<?> type is type-erasured, so ConverterService don't know how to deserialize the generic parameters
so pls
for example
ListItem.java
public class ListItem {
public int intVal;
public String strVal;
public ListItem(){}
public ListItem(int intVal, String strVal) {
this.intVal = intVal;
this.strVal = strVal;
}
}
ListTestServerResource.java
public class ListTestServerResource extends ServerResource {
@Get
public List<ListItem> getItemList() {
return Arrays.asList(new ListItem(1,"a"), new ListItem(2, "b"));
}
}
ExampleUnitTest.java
public class ExampleUnitTest {
@Before
public void setup() throws Exception {
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8088);
component.getClients().add(Protocol.FILE);
component.getDefaultHost().attach("/v1/list", ListTestServerResource.class);
component.start();
}
@Test
public void addition_isCorrect() throws IOException {
ClientResource clientResource = new ClientResource(new Context(), "http://127.0.0.1:8088/v1/list");
// this won't work, return List<LinkedHashMap> actually
List<ListItem> listItems = clientResource.get(List.class);
// this work
ListItem[] listItems1 = clientResource.get(ListItem[].class);
// this work also
JacksonRepresentation jacksonRepresentation = clientResource.get(JacksonRepresentation.class);
List<ListItem> listItems2 = jacksonRepresentation.getObjectMapper().readValue(jacksonRepresentation.getStream(), new TypeReference<List<ListItem>>() {
});
// this work also
InputStream inputStream = clientResource.get(InputStream.class);
List<ListItem> listItems3 = new ObjectMapper().readValue(inputStream, new TypeReference<List<ListItem>>() {
});
System.out.println(listItems1);
System.out.println(listItems2);
System.out.println(listItems3);
}
}
Upvotes: 0
Reputation: 116600
This is because a List
is a java.lang.Object
-- you asking for a List of Objects and that you are getting. Without additional type information, that is pretty much all you could possibly get. In your case, you should rather return User[]
(or List<User>
)
Upvotes: 0