2011-06-08 41 views
2
錯誤

使用澤西1.7,JAX-WS 2.2.3,Tomcat的6.0.30和下面的方法聲明防止澤西servlet來啓動:澤西:當一個類同時具有JAX-RS和JAX-WS註解

@POST 
@Produces("text/plain") 
public void postIt(@WebParam(name = "paramOne") final String paramOne, 
        final String paramTwo) { 
    // ... 
} 

發生的例外是:

SEVERE: Missing dependency for method public 
     java.lang.String com.sun.jersey.issue.MyResource.postIt(
      java.lang.String,java.lang.String) at parameter at index 0 
SEVERE: Method, public void 
     com.sun.jersey.issue.MyResource.postIt(
      java.lang.String,java.lang.String), 
     annotated with POST of resource, 
      class com.sun.jersey.issue.MyResource, 
      is not recognized as valid resource method. 

如果@WebParam註釋被刪除,這一切工作正常。

現在請記住,我並不是僅僅嘗試使用單純的字符串,而是將複雜的使用SOAP編組/解組的對象遷移到RESTful服務,但是我必須提供兩個接口一段時間,而沒有打破了之前的WASD。該方法只是一個簡約的場景。

你有沒有任何關於這個狀態的想法?它被修復了嗎?建議?

+0

我從來沒有在RESTful web服務中看到過'WebParam'註釋(即使我剛剛發現它在jax-rs包中存在)。你想做什麼?參數是來自查詢,路徑還是標題?你能否提供請求服務器的HTTP請求? – 2011-06-09 13:41:07

+0

'WebParam'註釋來自jax-ws。我想要實現的是使用相同的方法來處理SOAP,JSON,XML,純文本和HTML。對於SOAP,我使用的是Sun的jax-ws實現,其餘的我正在使用Jersey ...順便說一句,如果您使用WebParam,您將獲得WSDL而不是參數名稱,例如'arg0','arg1',您使用_pretty_名稱獲取參數。 – chahuistle 2011-06-09 21:43:21

+0

經過一些調試後,我發現這兩個參數缺少JAX-RS註釋,因此兩者都將從請求體中讀取。 JAX-RS 1.1(第3.3.2.1節)規定:「資源方法不能有多於一個參數,不用上面列出的註釋之一註釋。」,所以我的不好... – chahuistle 2011-06-16 20:05:19

回答

2

規格說明很明確。第3.3.2.1節告訴我們:

資源的方法不能未 與上述一個註釋所列 註釋更 不止一個參數。

列出註解以上所述JAX-RS參數註釋:@QueryParam@MatrixParam

有,然而,一個澤西特定的方式來解決這個問題。使用InjectableProvider。因此,一種方法是定義了兩個非JAX-RS參數:

@POST 
public void postIt(@CustomInjectable final Customer customer, 
        final Transaction transaction) { 
    // ... 
} 

當然,我們必須代碼註釋:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.PARAMETER) 
public @interface CustomInjectable { 
} 

InjectableProvider一個實現,它知道如何提供Customer S:

import com.sun.jersey.spi.inject.Injectable; 
import com.sun.jersey.spi.inject.InjectableProvider; 
import com.sun.jersey.api.model.Parameter; 

@Provider 
public class CustomerInjectableProvider implements 
      InjectableProvider<CustomInjectable, Parameter> { 

    // you can use @Context variables, as in any Provider/Resource 
    @Context 
    private Request request; 

    public ComponentScope getScope() { 
    // ComponentScope.Singleton, Request or Undefined 
    } 

    public Injectable getInjectable(ComponentContext i, 
            CustomInjectable annotation, 
            Parameter param) { 
    Injectable injectable = null; 
    if (Customer.getClass().isAssignableFrom(param.getParameterClass()) { 
     injectable = getInjectable(); 
    } 
    return injectable; 
    } 

    private Injectable getInjectable() { 
    return new Injectable<Customer>() { 
     public Customer getValue() { 
      // parse the customer from request... or session... or whatever...  
     } 
    }; 
    } 
} 

但是,澤西只考慮最後的註解(見JERSEY-ISSUE-731),所以要小心。

而且,更簡便的方式(如果你關心的是,反正):

// simple bean 
public class CustomerWithTransaction { 
    private Customer customer; 
    private Transaction transaction; 

    // getters and setters 
} 

然後改變方法:

@POST 
public void postIt(CustomerWithTransaction customerWithTransaction) { 
    // ... 
} 

然後自己MessageBodyReaderCustomerWithTransaction創建,你也可以訪問任何上下文變量(請求,頭文件等)。