【问题标题】:JAX-RS exception: Annotated with GET of resource, class is not recognized as valid resource methodJAX-RS 异常:用资源的 GET 注释,类不被识别为有效的资源方法
【发布时间】:2013-02-22 12:37:22
【问题描述】:

我正在为 Web 服务使用 JAX-RS 的 jersey 实现。我对这个 JAX-RS 很陌生。

我正在尝试在服务中添加一个方法,该方法接受一个 Employee 对象并根据 Employee 对象值返回员工 ID(为此有一个数据库命中)。

遵循Restful原则,我将方法设为@GET,并提供如下所示的url路径:

@Path("/EmployeeDetails")
public class EmployeeService {
@GET
@Path("/emp/{param}")
public Response getEmpDetails(@PathParam("param") Employee empDetails) {

    //Get the employee details, get the db values and return the Employee Id. 

    return Response.status(200).entity("returnEmployeeId").build();

}
}

出于测试目的,我写了这个客户端:

public class ServiceClient {

public static void main(String[] args) {

    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);
    WebResource service = client.resource(getBaseURI());

    Employee emp = new Employee();
    emp.name = "Junk Name";
    emp.age = "20";
    System.out.println(service.path("rest").path("emp/" + emp).accept(MediaType.TEXT_PLAIN).get(String.class));

}

private static URI getBaseURI() {
    return UriBuilder.fromUri("http://localhost:8045/AppName").build();
}

}

当我运行它时,我收到错误:Method, public javax.ws.rs.core.Response com.rest.EmployeeService.getEmpDetails(com.model.Employee), annotated with GET of resource, class com.rest.EmployeeService, is not recognized as valid resource method.

编辑:

型号:

package com.model;

public class Employee {

public String name;
public String age;

}

请让我知道问题出在哪里,我是这方面的初学者,正在努力理解这些概念:(

【问题讨论】:

  • 您确定不想传入employeeId 并返回Employee 对象。
  • 是的,我知道传递其他详细信息并获取 ID 是不寻常的,但这就是要求。如果有多个员工,则需要根据他们的加入日期获取最年长的员工,因此我确信我需要传递员工对象并获取员工 ID。你能告诉我如何使这项工作:(
  • EmployeeService 类的定义添加到问题中,包括任何类级别的注释。
  • 完成。请检查并让我知道问题

标签: java web-services rest service jax-rs


【解决方案1】:

JAX-RS 无法自动将@PathParam(它是一个字符串值)转换为Employee 对象。可以从 @PathParam 自动创建的对象的要求是:

  1. 字符串(事实上,因为数据已经是字符串)
  2. 具有接受(单个)字符串作为参数的构造函数的对象
  3. 具有静态valueOf(String) 方法的对象

对于情况 2 和 3,对象需要解析字符串数据并填充其内部状态。通常不会这样做(因为它会迫使您对数据的内容类型做出假设)。对于您的情况(刚开始学习 JAX-RS),最好只接受传入的 @PathParam 数据作为字符串(或整数,或长整数)。

@GET
@Path("/emp/{id}")
public Response getEmpDetails(@PathParam("id") String empId) {
    return Response.status(200).entity(empId).build();
}

在 GET 方法中将复杂的对象表示传递给 REST 服务没有多大意义,除非它被用作搜索过滤器。根据您的反馈,这就是您正在尝试做的事情。实际上,我之前在一个项目上做过这个(搜索过滤器的通用实现),需要注意的是您需要严格定义搜索数据的格式。因此,让我们将 JSON 定义为可接受的格式(您可以根据需要将该示例调整为其他格式)。 “搜索对象”将作为名为 filter 的查询参数传递给服务。

@GET
@Path("/emp")
public Response getEmployees(@QueryParam("filter") String filter) {
    // The filter needs to be converted to an Employee object. Use your
    // favorite JSON library to convert. I will illustrate the conversion
    // with Jackson, since it ships with Jersey
    final Employee empTemplate = new ObjectMapper().readValue(filter, Employee.class);

    // Do your database search, etc, etc
    final String id = getMatchingId(empTemplate);

    // return an appropriate response
    return Response.status(200).entity(id).build();
}

在您的客户端类中:

final String json = new ObjectMapper().writeValueAsString(emp);
service
    .path("rest")
    .path("emp")
    .queryParam("filter", json)
    .accept(emp, MediaType.TEXT_PLAIN)
    .get(String.class)

【讨论】:

  • 要求是接收员工的其他详细信息,并返回它的id。
  • 没有简单的方法将(复杂)对象表示作为路径参数传递。是需要使用@PathParam,还是只是将Employee 数据传递给Web 服务?
  • @Perception 不,只是将员工信息传递给Web服务参数。我对此并不陌生,因此除了使用@PathParam 之外,我不知道其他选项。除了使用@PathParam 来达到同样的效果之外,还有其他选择吗?感谢您的帮助。
  • @WhoAmI - 我对您的要求做了一些假设,并调整了我的答案。
  • 听起来您的要求是实现一种搜索。再次查看更新的答案。
【解决方案2】:

我遇到了同样的问题,但我刚刚修复了它 您的应用程序中使用的球衣 jar 应该具有相同的版本。

【讨论】:

    【解决方案3】:

    你想将一个实体(Employee)序列化为一个url路径段,这很奇怪。我不是说不可能,而是奇怪,然后你必须确保Employee 类满足以下条件(来自javadoc of@PathParam

    带注释的参数、字段或属性的类型必须是:
    ...(无关部分)
    有一个接受单个字符串参数的构造函数。
    有一个名为 valueOf 或 fromString 的静态方法,它接受单个 String 参数(例如,请参见 Integer.valueOf(String))。

    您可能希望在请求正文中而不是在路径参数中传递 Employee 对象。为此,请使用@XmlRootElement 注释Employee 类,从方法的empDetails 参数中删除@PathParam 注释,并将@GET 更改为@POST。

    【讨论】:

    • 是的,这就是重点。这就是我在想如何在不序列化的情况下在 URL 中传递员工对象,请多多包涵,因为我是初学者,今天是我的第二天。如果我尝试放入请求正文并返回请求,那么代码会是什么样子?你能发布一个相同的示例代码吗?
    • 您可以轻松找到好的示例/教程,只需在 google 上搜索“jax-rs 教程”即可。使用它们更容易,因为您可能会遇到那里已经详细解释过的问题。
    • 感谢您的意见。我尝试了这个链接:http://www.mkyong.com/webservices/jax-rs/download-xml-with-jersey-jaxb/ 他们接受一个字符串并返回与我想要实现的相反的 XML。仍然无法找到您的建议:(您能否发布一些链接,我可以在其中找到您的建议?感谢您的帮助
    • 如果您的对象不太复杂,将这两个字符串属性作为查询参数而不是对象序列化可能更容易。您可以找到有关 @QueryParam 用法的示例,例如在mkyong.com/webservices/jax-rs/jax-rs-queryparam-example
    • 绝对合法。您可以根据需要定义您的 api,并且在获取请求中接收消息正文甚至都行不通,AFAIK。
    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多