2011-12-07 7 views
16

Deseo enviar un objeto HashMap a un recurso ReST como una variable POST. Usé la clase Form para enviar el objeto. El código de cliente:envío de lista/mapa como POST parámetro jersey

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")); 
    } 

El recurso REST es el siguiente:

@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; 
    } 

} 

me sale el siguiente excepción en el 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) 

Es el código de cliente escrito por mí correcta ? ¿Hay alguna otra manera de enviar un objeto HashMap como variable POST?

Respuesta

28

Solo para aclarar un poco las cosas. El MultivaluedMap<String, String> está destinado a ser utilizado para obtener un mapa general de los parámetros del formulario, p. parámetros enviados a su servicio a través de solicitud POST HTTP. Se supone que debe ser utilizado de esta manera:

@POST 
    @Consumes("application/x-www-form-urlencoded") 
    public void post(MultivaluedMap<String, String> formParams) { 
    // Store the message 
    } 

Sin embargo, cuando la aplicación cliente tiene que proporcionar su servicio REST con algún tipo de datos (en su caso un HashMap contiene supongo que una gran cantidad de información importante) lo haría Serialízalo primero en XML, luego envíalo al servicio que luego lo deserializaría y usaría. Desafortunadamente, Jersey no puede ordenar/unmarrshal automáticamente HashMap s por lo que si proporcionó el parámetro HashMap en su método newProj, obtendrá una excepción.

Entonces, ¿cómo enviar un HashMap a su servicio? Bueno, la clave es la JAXB @XmlRootElement y una personalizada XmlAdapter :-)

Primero debe escribir su propia envoltura para el mapa. La envoltura se anota con @XmlRootElement

@XmlRootElement 
public class MyHashMapObject<T, U> { 
    private Map<T, U> mapProperty; 

    public MyHashMapObject() { 
     mapProperty = new HashMap<T, U>(); 
    } 

    @XmlJavaTypeAdapter(MapAdapter.class) // NOTE: Our custom XmlAdaper 
    public Map<T, U> getMapProperty() { 
     return mapProperty; 
    } 

    public void setMapProperty(Map<T, U> map) { 
     this.mapProperty = map; 
    } 
} 

Luego hay que definir su "JAXB activar" los elementos del mapa:

public class MapElement { 
    @XmlElement 
    public String key; 
    @XmlElement 
    public String value; 

    private MapElement() { 
    } 

    public MapElement(String key, String value) { 
     this.key = key; 
     this.value = value; 
    } 
} 

Y al final definir su XmlAdapter personalizado:

public class MapAdapter extends XmlAdapter<MapElement[], Map<String, String>> { 
    public MapElement[] marshal(Map<String, String> arg0) throws Exception { 
     MapElement[] mapElements = new MapElement[arg0.size()]; 
     int i = 0; 
     for (Map.Entry<String, String> entry : arg0.entrySet()) 
      mapElements[i++] = new MapElement(entry.getKey(), entry.getValue()); 

     return mapElements; 
    } 

    public Map<String, String> unmarshal(MapElement[] arg0) throws Exception { 
     Map<String, String> r = new HashMap<String, String>(); 
     for (MapElement mapelement : arg0) 
      r.put(mapelement.key, mapelement.value); 
     return r; 
    } 
} 

Una vez que tenga todo esto en su lugar (debe ser utilizado por su servicio y el cliente así que colóquelo en un jarrón de fragmentos), puede definir su servicio así:

@Path("/hello") 
public class FormResource 
{ 
    //@GET 
    @POST 
    @Produces(MediaType.APPLICATION_XML) 
    @Consumes(MediaType.APPLICATION_XML) 
    public MyHashMapObject<String, String> post(
       MyHashMapObject<String, String> anotherMap) { 

     anotherMap.getMapProperty().put("e", "10"); 
     anotherMap.getMapProperty().put("f", "11"); 
     anotherMap.getMapProperty().put("g", "12"); 

     return anotherMap; 
    } 
} 

Estás todo listo para ir ahora. Su cliente debe ir como esto:

public class Test { 
     public static void main(String[] args) { 
      ClientConfig config = new DefaultClientConfig(); 
      Client client = Client.create(config); 
      WebResource service = client.resource(getBaseURI()); 

      // Now do the MAP stuff 
      MyHashMapObject<String, String> map = new MyHashMapObject<String, String>(); 
      map.getMapProperty().put("a", "1"); 
      map.getMapProperty().put("b", "2"); 

      ClientResponse response = service.path("rest").path("hello2") 
       .type(MediaType.APPLICATION_XML) 
       .accept(MediaType.APPLICATION_XML) 
       .post(ClientResponse.class, map); 

      Map<String, String> myMap = response.getEntity(MyHashMapObject.class).getMapProperty();  
      for(Map.Entry<String, String> entry : myMap.entrySet()) 
       System.out.format("Key: %s, Value: %s\n", entry.getKey(), entry.getValue()); 

     } 

     private static URI getBaseURI() { 
      return UriBuilder.fromUri(
        "http://localhost:8080/org.nowaq.jersey.first").build(); 
     } 
    } 

Ahora puede pasar fácilmente a su HashMap<String, String> a su servicio REST. También puede hacer que la implementación sea un poco más genérica. Espero que esto ayude.

+0

muchas gracias !!!! :) –

+0

¿Funciona bien con las cargas de archivos? (¿Sería posible solucionar el problema en la pregunta de [aquí] (http://stackoverflow.com/questions/11020427/accepting-a-list-as-a-parameter-to-a-jersey-webservice)? -that-consume-a-content-t)?) – aioobe

+0

complejo uno :-( – vels4j

2

enviar mapa como petición del cuerpo de POST

@POST 
@Produces("application/json") 
@Consumes("application/json") 
@Path("/sendUser") 
public Response sendUser(Map<String,String> usersMap) { 
    String name = usersMap.get("Name"); 
    // first check for existing key 
    String family = usersMap.get("Family"); 
    String phone = usersMap.get("Phone"); 
    String mobile = usersMap.get("Mobile"); 
    return Response.ok("Get user attributes successfully !").build(); 
} 

Mapa Conseguir respuesta de la POST

@POST 
@Produces("application/json") 
@Consumes("application/json") 
@Path("/getUser") 
public Response getUser(String searchInputJsonString) { 
    Map<String,String> usersMap = new HashMap<>(); 
    usersMap.put("Name","Johm"); 
    usersMap.put("Family","W.R.Klein"); 
    usersMap.put("Phone","87540255"); 
    usersMap.put("Mobile", "112458033"); 
    return Response.ok(usersMap).build(); 
} 
1

Puede utilizar JSON.stringify (myMap) en javascript, y así pasar el mapa de stringyfied como parámetro de formulario.

en Java, que analizar la cadena de nuevo en un mapa como este:

@Path("doStuff") 
    @POST 
    @Produces(MediaType.APPLICATION_JSON) 
    public void doStuff(@FormParam("mapAsJson") String mapAsJson) throws JsonParseException, JsonMappingException, IOException { 
     @SuppressWarnings("unchecked") 
     HashMap<String,String> mapFromJson = (HashMap<String,String>)new ObjectMapper().readValue(mapAsJson, HashMap.class); 
     //add your processing 
    } 
Cuestiones relacionadas