4

我使用 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

4 回答 4

3

使用 Jackson 作为 Serializer/DeSerializer

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

重要的

确保Content-TypePOST请求中添加一个值为 的标头application/json。如果没有此标头,您Jersey可能不知道如何处理正文。

您将使用 Jackson将您的对象ObjectMapper序列化并发送到该对象,而不是那些东西。UnidadeJSONGenericType

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

于 2013-07-23T20:40:38.923 回答
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 个参数怎么办?因为 post 方法只接受 1

好吧,你不能用 JAX-RS 做到这一点,实际上它没有什么意义。您可以将多个参数作为@PathParam或 a传递给方法@MatrixParam,但只能有一个与主体相关联(那么我们的请求中只有一个主体,对吧?)。结帐此问题的答案结帐如何使用@PathParam@MatrixParam

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

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

于 2013-07-28T11:51:51.427 回答
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);
于 2013-07-24T03:38:15.477 回答
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 字符串创建。伪代码:

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

然后在您的 web 服务中只有一个表单参数来处理和反序列化;) 伪代码:

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

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

抱歉伪代码,但我已经关闭了我的开发虚拟机并且无法再访问任何存储库:(我认为这个解决方案的最大好处是:1.它可以传输任何你可以用 JSON 打包的东西。我传输 BASE64以这种方式编码的二进制块和高度加密的文本数据。2. POST 服务的 REST 框架的最简单的教程示例将提供您执行此操作所需的一切。3. 您可以确保您的界面将保持很长一段时间.

希望有帮助

于 2013-07-30T19:47:57.273 回答