Reputation: 1192
I'm trying to map all @QueryParam
of my JAX-RS Jersey
application to a JSON
data structure as follows:
@GET
@Produces("application/json")
@Path("/submit")
public String submit(@Context UriInfo info) {
MultivaluedMap<String, String> params = info.getQueryParameters();
JSONObject toInsert = new JSONObject();
toInsert.accumulate("id", params.get("id").get(0));
toInsert.accumulate("user", params.get("user").get(0));
//params.remove("id"); have also like to delete these two
//params.remove("user"); to avoid having duplicates in
// the next rows
JSONArray questions = new JSONArray();
for (Entry<String, List<String>> entry : params.entrySet()){
String[] values = (String[]) entry.getValue().toArray();
String key = entry.getKey();
questions.put(key, values);
}
toInsert.accumulate("questions", questions);
return toInsert;
}
Unfortunately I get an Exception
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
rest.Forms.submit(Forms.java:195)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:406)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:350)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:106)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:267)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:219)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
I also tried the following after reading this, it doesn't throw an exception but the result is semantically wrong. If I substitute the inner for loop as follows:
for (Entry<String, List<String>> entry : params.entrySet()){
List<String> values = entry.getValue();
String key = entry.getKey();
Object[] objectArray = values.toArray();
questions.put(key, Arrays.copyOf(objectArray, objectArray.length, String[].class));
}
The result in this case is composed in the "questions" part only as the list of keys, and I also want the associated values. Thank you in advance
{ "id" : "f5475dc0-c8ce-11e3-9c1a-0800200c9a66",
"questions" : [ "id",
"l_name",
"f_name",
"citizenship",
"like",
"user"
],
"user" : "gigi"
}
Upvotes: 1
Views: 779
Reputation: 10945
You can't actually cast the output of toArray()
in that fashion. You need to supply the type to the toArray()
call so that it returns an array of the appropriate type.
For instance:
List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
String[] arr1 = (String[]) list.toArray(); // this throws a ClassCastException
String[] arr2 = list.toArray(new String[0]); // this works
You just need to replace this line
String[] values = (String[]) entry.getValue().toArray();
with this one
String[] values = entry.getValue().toArray(new String[0]);
and your code should work.
Upvotes: 1