Jersey:类同时具有JAX-RS和JAX-WS注释时出错

时间:2011-06-08 16:44:06

标签: java jax-ws jersey jax-rs

使用Jersey 1.7,JAX-WS 2.2.3,Tomcat 6.0.30以及以下方法声明可防止Jersey servlet启动:

@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迁移到使用SOAP进行编组/解组的复杂对象,但是我必须提供两种接口,而不会破坏以前的WASD。该方法只是一种简约的方案。

你们有没有想过这个的状态?它被修复了吗?建议?

1 个答案:

答案 0 :(得分: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

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) {
  // ...
}

然后为MessageBodyReader创建自己的CustomerWithTransaction,您还可以在其中访问任何上下文变量(请求,标题等)。