I want to send a HashMap object to a ReST resource as a POST variable. I used the Form
class to send the object. The client code:
public static void main(String[] args)
{
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI());
HashMap<String, String> hashmap = new HashMap<String, String>();
hashmap.put("Key1", "value1");
hashmap.put("Key2", "value2");
Form form = new Form();
form.add("data1", hashmap);
ClientResponse response = service.path("hello2").path("hello2").type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class, form);
@SuppressWarnings("unchecked")
MultivaluedMap<String, String> map = response.getEntity(MultivaluedMap.class);
System.out.println(map.get("response").get(0));
System.out.println(map.get("response2"));
}
The REST resource is as follows:
@Path("/hello2")
public class FormResource
{
@Context
UriInfo uriInfo;
@Context
Request request;
public FormResource()
{
}
public FormResource(UriInfo uriInfo, Request request)// , String data1)
{
this.uriInfo = uriInfo;
this.request = request;
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public MultivaluedMap<String, String> newProj(@FormParam("data1") HashMap<String, String> postVarMap, @Context HttpServletResponse response)
{
System.out.println(postVarMap);
MultivaluedMap<String, String> hash = new MultivaluedMapImpl();
hash.add("response", "response1");
hash.add("response", "response2");
hash.add("response2", "fbshabfsdb");
URI uri = uriInfo.getAbsolutePathBuilder().build();
Response.created(uri).build();
return hash;
}
}
I get the following exception in the Tomcat 6.0 log
Dec 7, 2011 3:38:39 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/JerCDemo] has started
Dec 7, 2011 3:38:40 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.reflexis.nbe.jersey
Dec 7, 2011 3:38:40 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.reflexis.nbe.jersey.FormResource
Dec 7, 2011 3:38:40 PM com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
Dec 7, 2011 3:38:40 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.9.1 09/14/2011 02:05 PM'
Dec 7, 2011 3:38:40 PM com.sun.jersey.spi.inject.Errors processErrorMessages
SEVERE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Missing dependency for method public javax.ws.rs.core.MultivaluedMap com.reflexis.nbe.jersey.FormResource.newProj(java.util.HashMap,javax.servlet.http.HttpServletResponse) at parameter at index 0
SEVERE: Missing dependency for method public javax.ws.rs.core.MultivaluedMap com.reflexis.nbe.jersey.FormResource.newProj(java.util.HashMap,javax.servlet.http.HttpServletResponse) at parameter at index 0
SEVERE: Method, public javax.ws.rs.core.MultivaluedMap com.reflexis.nbe.jersey.FormResource.newProj(java.util.HashMap,javax.servlet.http.HttpServletResponse), annotated with POST of resource, class com.reflexis.nbe.jersey.FormResource, is not recognized as valid resource method.
Dec 7, 2011 3:38:40 PM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
com.sun.jersey.spi.inject.Errors$ErrorMessagesException
at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)
at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136)
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:771)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:766)
at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:488)
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:318)
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:609)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1173)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:993)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4420)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4733)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3460)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1357)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1649)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1658)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1658)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1638)
at java.lang.Thread.run(Thread.java:619)
Dec 7, 2011 3:38:40 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /JerCDemo threw load() exception
com.sun.jersey.spi.inject.Errors$ErrorMessagesException
at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)
at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136)
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:771)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:766)
at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:488)
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:318)
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:609)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1173)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:993)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4420)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4733)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3460)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1357)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1649)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1658)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1658)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1638)
at java.lang.Thread.run(Thread.java:619)
Is the client code written by me correct? Is there any other way to send a HashMap object as POST variable?
Just to clear things a bit. The
MultivaluedMap<String, String>
is meant to be used for obtaining general map of form parameters e.g. parameters submitted to your service via POST HTTP request. It is supposed to be used like this:However, when your client application needs to provide your REST service with some sort of data (in your case a
HashMap
containing I suppose a lot of important information) it would Serialize it to XML first, then send it to the service which would then deserialize and use it. Unfortunately, Jersey is not able to automatically marshal/unmmarshalHashMap
s so if you just providedHashMap
parameter in yournewProj
method, you would get an exception.So how to send a HashMap to your service? Well, the key is the JAXB
@XmlRootElement
and a customXmlAdapter
:-)First you need to write your own wrapper for the map. The wrapper will be annotated with
@XmlRootElement
Then you need to define your "JAXB enabled" map elements:
And in the end define your custom XmlAdapter:
Once you have all of this in place (it must be used by your service and the client so put it to some shard jar), you can define your service like this:
You're all set to go now. Your client should go like this:
Now you can easily pass your
HashMap<String, String>
to your REST service. You can also make the implementation a bit more generic. Hope this helps.You can use JSON.stringify(myMap) in javascript, and thus pass the stringyfied map as form parameter.
In java, you parse the string back into a map like this:
send Map as POST request body
get map response from POST