2011-12-07 32 views
16

Tôi muốn gửi đối tượng HashMap đến tài nguyên ReST dưới dạng biến POST. Tôi đã sử dụng lớp Form để gửi đối tượng. Mã khách hàng:gửi Danh sách/Bản đồ làm thông số POST 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")); 
    } 

Tài nguyên còn lại là như sau:

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

} 

tôi nhận được ngoại lệ sau đây trong 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) 

Là mã khách hàng bằng văn bản của tôi đúng ? Có cách nào khác để gửi đối tượng HashMap dưới dạng biến POST không?

Trả lời

28

Chỉ để xóa mọi thứ một chút. MultivaluedMap<String, String> được sử dụng để lấy bản đồ chung của các tham số biểu mẫu, ví dụ: các thông số được gửi tới dịch vụ của bạn thông qua yêu cầu POST HTTP. Đây là vụ phải được sử dụng như thế này:

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

Tuy nhiên, khi ứng dụng khách hàng của bạn cần phải cung cấp dịch vụ REST của bạn với một số loại dữ liệu (trong trường hợp của bạn một HashMap chứa Tôi cho rằng rất nhiều thông tin quan trọng) nó sẽ Tuần tự hóa nó thành XML trước, sau đó gửi nó đến dịch vụ mà sau đó sẽ deserialize và sử dụng nó. Thật không may, Jersey không thể tự động sắp xếp/unmmarshal HashMap s vì vậy nếu bạn chỉ cung cấp thông số HashMap trong phương thức newProj của mình, bạn sẽ nhận được ngoại lệ.

Vậy làm cách nào để gửi HashMap cho dịch vụ của bạn? Vâng, điều quan trọng là JAXB @XmlRootElement và :-)

tùy chỉnh trước tiên bạn cần phải viết trình bao bọc của riêng bạn cho bản đồ. Các wrapper sẽ được chú thích với @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; 
    } 
} 

Sau đó, bạn cần phải xác định trang "JAXB kích hoạt" các yếu tố bản đồ:

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

Và cuối cùng xác định XmlAdapter tùy chỉnh của bạn:

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

Một khi bạn có tất cả điều này tại chỗ (nó phải được sử dụng bởi dịch vụ của bạn và khách hàng để đặt nó vào một số lọ shard), bạn có thể xác định dịch vụ của bạn như thế này:

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

Bạn đã sẵn sàng hoàn tất ngay bây giờ. Khách hàng của bạn nên thực hiện như sau:

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

Bây giờ bạn có thể dễ dàng chuyển số HashMap<String, String> sang dịch vụ REST của mình. Bạn cũng có thể làm cho việc triển khai thực hiện chung chung hơn một chút. Hi vọng điêu nay co ich.

+0

THANKS rất nhiều !!!! :) –

+0

Tính năng này có hoạt động tốt với các tệp tải lên không? (Nó sẽ là một công việc có thể xung quanh cho vấn đề trong câu hỏi trên [ở đây] (http://stackoverflow.com/questions/11020427/accepting-a-list-as-a-parameter-to-a-jersey-webservice -that-consumes-a-content-t)?) – aioobe

+0

phức tạp như vậy :-( – vels4j

2

gửi đồ theo yêu cầu của cơ thể 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(); 
} 

phản ứng get bản đồ từ 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

Bạn có thể sử dụng JSON.stringify (myMap) trong javascript, và do đó vượt qua bản đồ dạng chuỗi như là tham số biểu mẫu.

Trong java, bạn phân tích chuỗi lại thành một bản đồ như thế này:

@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 
    } 
Các vấn đề liên quan