JAX-RS异常:使用资源的GET进行批注,类不被视为有效的资源方法

时间:2013-02-22 12:37:23

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

我正在使用JAX-RS的平针织实现来进行Web服务。我对这个JAX-RS很新。

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

遵循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;

}

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

3 个答案:

答案 0 :(得分:5)

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

  1. String(事实上,因为数据已经是一个字符串)
  2. 具有接受(单个)字符串作为参数的构造函数的对象
  3. 具有静态valueOf(String)方法的对象
  4. 对于案例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)
    

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

  

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

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