使用 Jersey 1.x 自定义注解注入

Custom annotation injection with Jersey 1.x

I am using jersey 1.9.1. I have rest method like following where Authorization header contained encoded credentials such as username and password and it is parsed in a method and mapped local values.

@PUT
@Path(SystemConstants.REST_MESSAGE_SENDSMS)
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON})
public Response sendSms(@HeaderParam("Authorization") String authorization, String param) {

    String[] credentials = ImosUtils.getUserCredentials(authorization);
    String username = credentials[0];
    String password = credentials[1];       
    }

我正在尝试设计一种方法来自动执行此过程,而无需在每个方法中编写相同的解析代码。我的意思是我想知道是否为此编写了一个特殊的注释,例如 HeaderParamExtended 用于解析此凭据。
我正在使用 jersey 1.9.1 版本作为休息 api。在那个生命周期中我必须在哪里编辑 class?

@PUT
@Path(SystemConstants.REST_MESSAGE_SENDSMS)
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON})
public Response sendSms(@HeaderParamExtended("Authorization","username") String username, @HeaderParamExtended("Authorization","password") String password, , String param) {


    }

通常您需要 InjectableProvider to support the custom injection, and also an Injectable 来提供值。

这是一个例子

@BasicAuth

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

InjectableProvider

@Provider
public class BasicAuthInjectionProvider
        implements InjectableProvider<BasicAuth, Parameter> {

    @Override
    public ComponentScope getScope() {
        return ComponentScope.PerRequest;
    }

    @Override
    public Injectable getInjectable(ComponentContext cc, BasicAuth a, Parameter c) {
        return new BasicAuthInjectable();
    }
}

Injectable

public class BasicAuthInjectable extends AbstractHttpContextInjectable<User>{

    @Override
    public User getValue(HttpContext hc) {
        String authHeaderValue = hc.getRequest()
                .getHeaderValue(HttpHeaders.AUTHORIZATION);
        String[] credentials = ImosUtils.getUserCredentials(authHeaderValue);

        return new User(credentials[0], credentials[1]);
    }  
}

你会注意到我有一个 User class。这是把usernamepassword包裹起来,只有一个注入点。即

public Response getSomething(@BasicAuth User user) {
}

我实际上试着按照你的方式去做,

public Response getSomething(@BasicAuth("username") String username,
                             @BasicAuth("password") String password) {

并在 InjectableProvider 中从传递给 getInjectable 的注释中获取注释值,然后将该值传递给 BasicAuthInjectable。从那里检查值是否为 "username""password" 和 return 对应的值。但出于某种原因,注入提供者甚至没有被调用。您可以尝试一下,看看是否可以正常工作。但对我来说 User 看起来更干净了,并且对于两个字符串,注入提供程序被调用两次,你需要解析 headers 两次。好像没必要。