sending List/Map as POST parameter jersey

前端 未结 3 1901
情歌与酒
情歌与酒 2020-12-02 19:20

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         


        
相关标签:
3条回答
  • 2020-12-02 19:55

    send Map as POST request body

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

    get map response from 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();
    }
    
    0 讨论(0)
  • 2020-12-02 19:57

    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:

        @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 
        }   
    
    0 讨论(0)
  • 2020-12-02 20:03

    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:

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

    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/unmmarshal HashMaps so if you just provided HashMap parameter in your newProj method, you would get an exception.

    So how to send a HashMap to your service? Well, the key is the JAXB @XmlRootElement and a custom XmlAdapter :-)

    First you need to write your own wrapper for the map. The wrapper will be annotated with @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;
        }
    }
    

    Then you need to define your "JAXB enabled" map elements:

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

    And in the end define your custom XmlAdapter:

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

    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:

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

    You're all set to go now. Your client should go like this:

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

    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.

    0 讨论(0)
提交回复
热议问题