在客户端传递参数

时间:2013-07-21 18:00:21

标签: java web-services rest

我使用RESTful Web服务。在这个Web服务中,我必须传递一个我想要保存为参数的bean。

这是服务器代码:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Unidade inserir(Unidade unidade){
    Session s = ConnectDb.getSession();
    try {
        s.getTransaction().begin();
        s.save(unidade);
        s.getTransaction().commit();
        return unidade;
    } catch (Exception e) {
        e.printStackTrace();
        s.getTransaction().rollback();
        return null;
    } finally {
        s.close(); 
    }
}

我在客户端中有以下代码:

ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource webResource = client.resource("http://localhost:8080/RestauranteWeb/rest/unidades/7");
Builder builder = webResource.accept(MediaType.APPLICATION_JSON); 
GenericType<Unidade> genericType = new GenericType<Unidade>() {};

Unidade u = new Unidade();
u.setUnidSigla("KG");
//How to pass this bean as parameter?

Unidade response = builder.post(genericType);
System.out.println(response);

如何将bean作为参数传递给方法?

4 个答案:

答案 0 :(得分:3)

使用Jackson作为Serializer / DeSerializer

如果您的Unidade对象已使用杰克逊注释和/或Deserializer已注册,那么您应该能够POST使用包含{{1}的BODY表示JSON对象。它应该神奇地反序列化并重建为服务器端的对象。

重要

确保在Unidade请求中添加Content-Type标头,其值为POST。如果没有此标题,您application/json可能不知道如何处理身体。

您可以使用杰克逊JerseyObjectMapper对象序列化为Unidade并发送该对象而不是JSON内容。

我有Jersey和RESTEasy实现,以这种方式与Jackson无缝协作。

答案 1 :(得分:2)

  

如何将bean作为参数传递给方法?

查看post方法的文档:

 /**
 * Invoke the POST method with a request entity that returns a response.
 * 
 * @param <T> the type of the response.
 * @param c the type of the returned response.
 * @param requestEntity the request entity.
 * @return an instance of type <code>c</code>.
 * @throws UniformInterfaceException if the status of the HTTP response is 
 *         greater than or equal to 300 and <code>c</code> is not the type
 *         {@link ClientResponse}.
 * @throws ClientHandlerException if the client handler fails to process
 *         the request or response.
 */
<T> T post(Class<T> c, Object requestEntity) 
        throws UniformInterfaceException, ClientHandlerException;

该方法有两个参数。第一个参数是预期的响应类型,第二个参数是将放入请求主体的实体。

这里发生的事情,在执行请求时,Jersey会将作为请求实体传递的对象序列化为JSON字符串(因此您设置了标题 - accept(MediaType.APPLICATION_JSON))。当来自服务器的响应到达时,Jersey将反序列化它(如requestEntity的情况下的反转过程)并返回对象。

  

如果我的方法收到多个参数怎么办?因为帖子   方法只有1个

嗯,你不能用JAX-RS做到这一点,实际上没什么意义。您可以将多个参数作为@PathParam@MatrixParam传递给方法,但只有一个参数与正文相关联(您的请求中只有一个正文,对吧?)。 Checkout answer to this questioncheckout how to use @PathParam@MatrixParam

  

我们假设我的方法不是返回“Unidade”类   返回一个String。因此,它会收到一个“Unidade”作为参数和   返回一个“字符串”。如何在这种情况下检索它,传递   “Unidade”实例和以前一样?

我相信你可以通过post(String.class, unidadeInstance)实现这一目标。第一个参数不必与第二个参数相同。接受一个参数并返回另一个参数是有效的。获取参数并在正文中不返回任何内容甚至是有效的(就像您在附加到您的问题的代码中所做的那样)。您可以接受正文并发回包含状态201 CreatedLocation标题条目的响应,该标题条目指向新创建的资源的URL。

答案 2 :(得分:1)

不确定GenericType的目的是什么。无论如何,请尝试下面的代码。

ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
Unidade u = new Unidade();
u.setUnidSigla("KG");
WebResource webResource = client.resource("http://localhost:8080/RestauranteWeb/rest/unidades/7");
Unidade response = webResource.accept(MediaType.APPLICATION_JSON)
                          .type(MediaType.APPLICATION_JSON)
                           .post(Unidade.class, u);

答案 3 :(得分:0)

我不确定它是否有帮助,但我遇到了类似的问题。 我的情况是我需要一个Web服务,它必须接收一组值作为一种配置文件组织的值。但是,这项服务必须处理更多的配置文件,其中仍有旧客户使用该服务。界面必须尽可能保持静态。

我们的解决方案非常简单。我们只发布一个文本字段作为帖子的内容。但这包括JSON中配置文件对象的序列化状态。 伪代码:

public class Profile1 {
  ...

  public String asJSON() {
    JSONObject obj = new JSONObject();
    obj.put("profileAtr1", profileAtr1);
    ...
    return obj.toString()
  }
}

formParams.put("profile", profile.asJSON());
client.post(formParams);

这种方式不会自动反序列化,但手动操作很容易。 我们使用通用的Profile对象来完成此操作,该对象可以在构造函数中使用JSON String创建。 伪代码:

public GenericProfile {
  public GenericProfile(String json) {
    JSONObject obj = new JSONObject(json);
    String profileName = obj.getString("profileName");

    if (profileName.equals("Profile1") {
      this = new Profile1(obj);   // I know this is not working ;) My impl. is a litle bit more complecated as that. I think i use a static method in the generic profile to create an instance i need.
    } ...
  }
}

然后在你的webservice中只有一个表格参数来处理和反序列化;) 伪代码:

public ResponseEnvelope coolServiceFunction(@FormParam("profile") String profileData) {
  GenericProfile profile = new GenericProfile(profileData);

  if (profile instanceof Profile1) {
    do what you want
  }
}

抱歉伪代码,但我已经关闭了我的dev vm并且无法访问任何存储库:( 我认为这个解决方案的最大好处是: 它可以运输你可以用JSON打包的任何东西。我以这种方式传输BASE64编码的二进制块和重度加密的textdata。 2. POST服务的REST框架最简单的教程示例将提供执行此操作所需的全部内容。 3.您可以确定您的界面会保留很长一段时间。

希望有所帮助