競標書REST風格的Java與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方法 將處理HTTP GET請求的URI。您可以使用 之前描述的其他五個註釋之一綁定到 不同的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());
}
}
這種限制有什麼困擾你?是否需要複製註釋? – eiden 2013-05-10 21:10:20