引用RESTful Java with JAX-RS一书:
JAX-RS 定义了五个映射到特定 HTTP 操作的注解:
@javax.ws.rs.GET
@javax.ws.rs.PUT
@javax.ws.rs.POST
@javax.ws.rs.DELETE
@javax.ws.rs.HEAD
(...)
注释@GET
指示 JAX-RS 运行时此 Java 方法将处理对 URI 的 HTTP GET 请求。您将使用前面描述的其他五个注释之一来绑定到不同的 HTTP 操作。不过需要注意的一点是,您只能为每个 Java 方法应用一个 HTTP 方法注释。如果您应用多个,则会发生部署错误。
(以上文字由 RESTEasy 的创建者编写。)
而且,简而言之,由于 RESTEasy 符合 JAX-RS,您不能使用多个 HTTP 动词注释方法。
如果你不服气,看一下注解,@GET
你会发现它只是一个元注解。@HttpMethod
/**
* Indicates that the annotated method responds to HTTP GET requests
* @see HttpMethod
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod(HttpMethod.GET)
public @interface GET {
}
如果您打开@HttpMethod
,请检查 javadoc (使用多个注释注释的方法是错误的HttpMethod
。注释):
/**
* Associates the name of a HTTP method with an annotation. A Java method annotated
* with a runtime annotation that is itself annotated with this annotation will
* be used to handle HTTP requests of the indicated HTTP method. It is an error
* for a method to be annotated with more than one annotation that is annotated
* with {@code HttpMethod}.
*
* @see GET
* @see POST
* @see PUT
* @see DELETE
* @see HEAD
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpMethod
{
所以,就是这样,你不能在同一种方法中同时拥有它们。
也就是说,如果你真的必须,你可以通过PreProcessInterceptor
在 JAX-RS 方法之前调用的方法来实现这一点。
尽管如此,这种方式要复杂得多(因为您必须自己解析参数)并且可维护性要差得多(在拦截器处提供服务!?)。
底线,据我所知,您的解决方案是最佳的。
检查我在下面的测试中所说的内容:
public class QueryAndFormParamTest {
@Path("/")
public static class InterceptedResource {
@GET
//@Path("/stuff") // uncomment this and it will not work
public String otherService(@QueryParam("yadda") String name){
return "Im never called in this example" + name;
}
}
public static class MyInterceptor implements PreProcessInterceptor, AcceptedByMethod {
@Override
public boolean accept(Class declaring, Method method) {
System.out.println("Accepted by method "+method.getName());
// you can check if this interceptor should act on this method here
return true; // it'll act everytime
}
@Override
public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
throws Failure, WebApplicationException {
// parsing form parameters
if (request.getHttpHeaders().getMediaType() != null && request.getHttpHeaders().getMediaType().isCompatible(MediaType.valueOf("application/x-www-form-urlencoded"))) {
MultivaluedMap<String, String> formParameters = request.getFormParameters();
if (formParameters != null) {
for (String key : formParameters.keySet()) {
System.out.println("[FORM] "+key + ": "+formParameters.get(key));
}
}
}
// parsing query parameters
MultivaluedMap<String, String> queryParameters = request.getUri().getQueryParameters();
if (queryParameters != null)
for (String key : queryParameters.keySet()) {
System.out.println("[QUERY] "+key + ": "+queryParameters.get(key));
}
String responseText = "do something: " + request.getUri().getQueryParameters().getFirst("test");
return new ServerResponse(responseText, 200, new Headers<Object>());
}
}
@Test
public void test() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getProviderFactory().getServerPreProcessInterceptorRegistry().register(new MyInterceptor());
dispatcher.getRegistry().addSingletonResource(new InterceptedResource());
MockHttpRequest request = MockHttpRequest.get("/?test=someStuff");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
System.out.println(response.getContentAsString());
Assert.assertEquals("do something: someStuff", response.getContentAsString());
}
}