2011-06-08 36 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创建,你也可以访问任何上下文变量(请求,头文件等)。