Java 在客户端中传递参数

Java 在客户端中传递参数,java,web-services,rest,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.getTransac

我使用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);
ClientConfig config=newdefaultclientconfig();
Client=Client.create(config);
WebResource WebResource=client.resource(“http://localhost:8080/RestauranteWeb/rest/unidades/7");
Builder=webResource.accept(MediaType.APPLICATION\ujson);
GenericType GenericType=新的GenericType(){};
Unidade u=新Unidade();
u、 setUnidSigla(“KG”);
//如何将这个bean作为参数传递?
Unidade响应=builder.post(genericType);
System.out.println(响应);
如何将bean作为参数传递给方法?

使用Jackson作为序列化器/反序列化器 如果您的
Unidade
对象用Jackson注释,并且/或者注册了
反序列化器
,那么您应该能够
POST
使用
主体
,该主体包含表示
Unidade
对象的
JSON
。它应该被神奇地反序列化并在服务器端重建为对象

重要的 确保在
POST
请求中添加一个
Content-Type
标题,其值为
application/json
。没有此标题,您的
球衣可能不知道如何处理身体

您可以使用Jackson
ObjectMapper
将您的
Unidade
对象序列化为
JSON
并发送它,而不是发送任何
GenericType
内容


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

不确定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);
如何将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;
该方法采用两个参数。第一个参数是预期的响应类型,第二个参数是将放入请求主体中的实体

这里发生的事情是,当执行请求时,会将作为请求实体传递的对象序列化为JSON字符串(因此您设置了头-
accept(MediaType.APPLICATION\u JSON)
)。当来自服务器的响应到达时,Jersey将对其进行反序列化(与
requestEntity
的情况相反),并返回对象


如果我的方法接收到多个参数呢?因为邮报 方法1

您不能用JAX-RS来实现它,而且实际上它没有什么意义。您可以将多个参数作为
@PathParam
@MatrixParam
传递给方法,但只能有一个与主体关联(在我们的请求中您只有一个主体,对吗?)。或

让我们假设我的方法不是返回“Unidade”类,而是 返回一个字符串。因此,它将接收一个“Unidade”作为参数 返回一个“字符串”。在这种情况下,如何通过 “Unidade”的例子和以前一样吗


我相信您可以通过
post(String.class,unidadeInstance)
实现这一点。第一个参数不必与第二个参数相同。接受一个参数并返回另一个参数是有效的。甚至在主体中不返回任何参数也是有效的(就像您在问题所附的代码中所做的那样)。您可以接受正文并返回包含状态
201 Created
Location
标题项的响应,标题项指向新创建的资源的URL。

我不确定这是否有帮助,但我遇到了类似的问题。 我的场景是我需要一个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);
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.
    } ...
  }
}
public ResponseEnvelope coolServiceFunction(@FormParam("profile") String profileData) {
  GenericProfile profile = new GenericProfile(profileData);

  if (profile instanceof Profile1) {
    do what you want
  }
}
通过这种方式,它不是自动反序列化的,但很容易手工实现。 我们使用一个通用概要文件对象来实现这一点,该对象可以在构造函数中用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);
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.
    } ...
  }
}
public ResponseEnvelope coolServiceFunction(@FormParam("profile") String profileData) {
  GenericProfile profile = new GenericProfile(profileData);

  if (profile instanceof Profile1) {
    do what you want
  }
}
然后在您的Web服务中,只有一个表单参数要处理和反序列化;) 伪代码:

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);
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.
    } ...
  }
}
public ResponseEnvelope coolServiceFunction(@FormParam("profile") String profileData) {
  GenericProfile profile = new GenericProfile(profileData);

  if (profile instanceof Profile1) {
    do what you want
  }
}
很抱歉出现了伪代码,但我已经alleady关闭了我的开发虚拟机,无法再访问任何存储库:( 我认为此解决方案的最大好处是: 1.它可以传输任何可以用JSON打包的东西。我用这种方式传输BASE64编码的二进制块和高度加密的文本数据。 2.POST服务的REST框架的最简单教程示例将提供您所需的全部内容。 3.您可以确保您的界面将保留很长一段时间


希望这会有所帮助

但是我如何使用上面的代码呢?或者我不应该为客户端使用Jersey api吗?我使用的是最新版本的Apache Commons
HTTPClient
,因为Jersey客户端是单线程的,并且有一些我不想解决的其他限制。好吧,它可以工作!但是我不太清楚您在哪里定义请求和定义响应的位置(方法的参数和方法的返回)。假设我的方法不返回“Unidade”类,而是返回一个字符串。因此,它将接收一个“Unidade”作为参数并返回一个“字符串”。在这种情况下,我如何通过传递“Unidade”来检索它实例?如果我的方法接收到多个参数怎么办?因为post方法只接收1个参数。