java JAX-RS 异常:用资源的 GET 注释,类不被识别为有效的资源方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15024408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAX-RS exception: Annotated with GET of resource, class is not recognized as valid resource method
提问by WhoAmI
I am using the jersey implementation of JAX-RS for the web service. I am very new to this JAX-RS.
我正在将 JAX-RS 的 jersey 实现用于 Web 服务。我对这个 JAX-RS 很陌生。
I am trying to add a method in the service which accept an Employee object and returns the employee Id based on the Employee object values (there is a DB hit for this).
我正在尝试在服务中添加一个方法,该方法接受一个 Employee 对象并根据 Employee 对象值返回员工 ID(为此有一个 DB 命中)。
Following the Restful principles, I made the method as @GET and provided the url path as shown below:
遵循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();
}
}
For testing purpose, I wrote this Client:
出于测试目的,我写了这个客户端:
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();
}
}
}
When I run it, I am getting the error: 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.
当我运行它时,我收到错误: 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.
Edit:
编辑:
Model:
模型:
package com.model;
public class Employee {
public String name;
public String age;
}
Please let me know where is the issue, I am a beginner in this and struggling to understand the concepts :(
请让我知道问题出在哪里,我是这方面的初学者并且正在努力理解这些概念:(
回答by Perception
JAX-RS cannot automatically convert a @PathParam (which is a string value), into an Employee
object. Requirements for objects that can be automatically created from a @PathParam are:
JAX-RS 无法自动将 @PathParam(它是一个字符串值)转换为一个Employee
对象。可以从 @PathParam 自动创建的对象的要求是:
- String (defacto, because the data is already a string)
- Objects with a constructor that accepts a (single) string as argument
- Objects with a static
valueOf(String)
method
- 字符串(事实上,因为数据已经是字符串了)
- 具有接受(单个)字符串作为参数的构造函数的对象
- 具有静态
valueOf(String)
方法的对象
For cases 2 & 3 the object would be required to parse the string data and populate its internal state. This is not normally done (because it forces you to make assumptions about the content type of the data). For your situation (just beginning to learn JAX-RS), its best to just accept the incoming @PathParam data as a String (or Integer, or Long).
对于情况 2 和 3,对象需要解析字符串数据并填充其内部状态。通常不会这样做(因为它迫使您对数据的内容类型做出假设)。对于您的情况(刚开始学习 JAX-RS),最好只接受传入的 @PathParam 数据作为字符串(或整数或长整数)。
@GET
@Path("/emp/{id}")
public Response getEmpDetails(@PathParam("id") String empId) {
return Response.status(200).entity(empId).build();
}
Passing a complex object representation to a REST service in a GET method doesn't make much sense, unless its being used, eg, as a search filter. Based on your feedback, that is what you are trying to do. I've actually done this on a project before (generic implementation of search filters), the one caveat being that you need to strictly define the format of the search data. So, lets define JSON as the accepted format (you can adapt the example to other formats as needed). The 'search object' will be passed to the service as a query parameter called filter
.
在 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 Hymanson, 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();
}
And in your client class:
在您的客户课程中:
final String json = new ObjectMapper().writeValueAsString(emp);
service
.path("rest")
.path("emp")
.queryParam("filter", json)
.accept(emp, MediaType.TEXT_PLAIN)
.get(String.class)
回答by Super Hornet
I got the same issue but I just fixed it jersey jars used in your application should have same versions.
我遇到了同样的问题,但我只是修复了它,您的应用程序中使用的球衣罐应该具有相同的版本。
回答by zagyi
It's quite strange that you want to serialize an entity (Employee) into an url path segment. I'm not saying it's impossible, but strange, and then you have to make sure that the Employee
class satisfies the following criteria (which is from the javadoc of@PathParam
)
你想把一个实体(Employee)序列化成一个url路径段,这很奇怪。我不是说这是不可能的,但很奇怪,然后您必须确保Employee
该类满足以下条件(来自 的javadoc@PathParam
)
The type of the annotated parameter, field or property must either:
... (irrelevant part)
Have a constructor that accepts a single String argument.
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String)).
带注释的参数、字段或属性的类型必须:
...(无关部分)
具有接受单个 String 参数的构造函数。
有一个名为 valueOf 或 fromString 的静态方法,它接受单个 String 参数(例如,参见 Integer.valueOf(String))。
You might want to pass the Employee
object in the request body raher than in a path param. To chieve this, annotate the Employee
class with @XmlRootElement
,remove the @PathParam
annotation from the method's empDetails
argument, and change @GET to @POST.
您可能希望Employee
在请求正文中传递对象而不是在路径参数中传递。要实现这一点,请使用 注释Employee
类@XmlRootElement
,@PathParam
从方法的empDetails
参数中删除注释,并将@GET 更改为@POST。