【问题标题】:RESTful Webservice does not handle Request Method properlyRESTful Webservice 无法正确处理请求方法
【发布时间】:2012-06-06 18:44:58
【问题描述】:

我正在从多个 RESTful Web 服务方法中检索值。 在这种情况下,由于请求方法的问题,两种方法相互干扰。

@GET
@Path("/person/{name}")
@Produces("application/xml")
public Person getPerson(@PathParam("name") String name) {
    System.out.println("@GET /person/" + name);
    return people.byName(name);
}

@POST
@Path("/person")
@Consumes("application/xml")
public void createPerson(Person person) {
    System.out.println("@POST /person");
    System.out.println(person.getId() + ": " + person.getName());
    people.add(person);
}

当我尝试使用以下代码调用 createPerson() 方法时,我的 Glassfish 服务器将生成“@GET /person/ 我尝试在其上创建人的名称”。这意味着调用了 @GET 方法,即使我没有发送 {name} 参数(正如您在代码中看到的那样)。

URL url = new URL("http://localhost:8080/RESTfulService/service/person");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/xml");
connection.setDoOutput(true);
marshaller.marshal(person, connection.getOutputStream());

我知道这要求对我的代码进行大量挖掘,但在这种情况下我做错了什么?

更新

因为 createPerson 是 void,所以我不处理 connection.getInputStream()。 这实际上似乎导致我的服务未处理请求。

但是实际的请求是在connection.getOutputStream()上发送的,对吧?

更新 2

RequestMethod 确实有效,只要我处理一个带有返回值的方法,因此是 connection.getOutputStream()。当我尝试调用 void 并因此不处理 connection.getOutputStream() 时,服务将不会收到任何请求。

【问题讨论】:

  • 如果使用 cURL 会怎样? curl -X POST http://localhost:8080/RESTfulService/service/person
  • 尝试从您的请求中删除接受标头
  • 对此我不确定。试图帮助你调试。我们需要弄清楚为什么要调用 GET。那么顺序重要吗?可能是 GET 是“/person” url 模式的第一个匹配项
  • 我认为带有 JAX-RS 注释的方法必须返回一些东西。尝试用字符串替换 void 返回类型并返回任何内容。
  • 我可以确认删除接受标头不会产生影响。

标签: java rest request jax-rs


【解决方案1】:

您应该设置“Content-Type”而不是“Accept”标头。 Content-Type 指定发送给接收者的媒体类型,而 Accept 是关于客户端接受的媒体类型。有关标头的更多详细信息是here

这里是 Java 客户端:

public static void main(String[] args) throws Exception {
    String data = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><person><name>1234567</name></person>";
    URL url = new URL("http://localhost:8080/RESTfulService/service/person");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/xml");

    connection.setDoOutput(true);
    connection.setDoInput(true);        

    OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
    wr.write(data);
    wr.flush();

    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    wr.close();
    rd.close();

    connection.disconnect();
}

使用 curl 也是一样的:

curl -X POST -d @person --header "Content-Type:application/xml" http://localhost:8080/RESTfulService/service/person

,其中“person”是包含 xml 的文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><name>1234567</name></person>

【讨论】:

  • 或者你也可以在这两个方法中添加@Produces("application/xml") @Consumes("application/xml") 然后再试一次。我认为在这种情况下它也需要运行。
  • 一个 HTTP 连接有一个请求和响应,所以我需要阅读响应。同样,一个方法最好返回某种关于其成功的状态,然后读取响应会更有意义。
猜你喜欢
  • 1970-01-01
  • 2019-04-05
  • 2012-01-14
  • 2014-09-23
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多