Java Jersey 1.x的自定义注释注入

Java Jersey 1.x的自定义注释注入,java,rest,jakarta-ee,annotations,jersey,Java,Rest,Jakarta Ee,Annotations,Jersey,我正在使用jersey 1.9.1。我有如下的休息方法 授权标头包含编码凭据,如用户名 密码,然后在方法中解析它并映射本地值 我正试图设计一种方法,使这个过程自动进行,而不必在每个方法中编写相同的解析代码。我的意思是,我想知道是否要使用为其编写一个特殊注释,如HeaderParamExtended,来解析此凭据。 我使用jersey 1.9.1版本作为RESTAPI。在该生命周期中,我必须在哪里编辑类 @PUT @Path(SystemConstants.REST_MESSAGE_SENDSMS

我正在使用jersey 1.9.1。我有如下的休息方法 授权标头包含编码凭据,如用户名 密码,然后在方法中解析它并映射本地值

我正试图设计一种方法,使这个过程自动进行,而不必在每个方法中编写相同的解析代码。我的意思是,我想知道是否要使用为其编写一个特殊注释,如
HeaderParamExtended
,来解析此凭据。
我使用jersey 1.9.1版本作为RESTAPI。在该生命周期中,我必须在哪里编辑类

@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) {


    }
通常,您需要一个来支持自定义注入,还需要一个来提供值

这里有一个例子

@BasicAuth

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface BasicAuth {
}
@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();
    }
}
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]);
    }  
}
InjectableProvider

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface BasicAuth {
}
@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();
    }
}
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
类。这是为了包装
用户名
密码
,并且只有一个注入点。i、 e

public Response getSomething(@BasicAuth User user) {
}
我真的试着用你的方式做了

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

InjectableProvider
中,从传递到
getInjectable
的注释中获取注释值,然后将该值传递到
BasicAuthInjectable
。从那里检查值是否为
“username”
“password”
,并返回相应的值。但出于某种原因,注射供应商甚至没有接到电话。你可以玩玩它,看看能否让它发挥作用。但是对我来说,
用户
看起来更干净,使用这两个字符串,注入提供者会被调用两次,您需要解析两次头。似乎没有必要。

我最近做了一些非常类似的事情(即认证服务)。我使用AspectJ是为了在每个服务中都没有用于验证用户的代码。我不知道这样一种方法是否对您有用,但在我的例子中,使用方面是一个非常好的解决方案。您不能在web.xml级别添加“安全性”吗?这样调用就不会出现在您的方法中,并且事先得到验证?或者在您的服务中添加一个过滤器,用于拦截并在一个位置执行此授权部分?我已经有了这样的级别来进行身份验证,但我必须使用每个请求的用户名,因此我需要在身份验证后将其传递到服务级别。我在部署时遇到以下错误,com.sun.jersey.spi.inject.Errors$ErrorMessagesException:com.sun.jersey.spi.inject.Errors.ErrorMessagesException:nullI使用1.19测试。让我把它改成1.9.1,看看我是否也遇到同样的问题。是的,刚刚用Jersey 1.9.1测试过。它很好用。如果未对提供者和资源类使用扫描,
@Provider
注释将不会被拾取,您需要显式注册提供者。也许这就是问题所在。不确定。如果您想创建一个小的Github项目来重现这个问题,我可以看看它。否则,该错误片段不足以发现问题。我已创建了示例文件,但credentialbean未初始化。“CredentialBean:username:null,password:null”我已经测试过了,它在启动时没有给出任何异常。我面临的唯一问题是通过将
com.mkyong.auth
包添加到要在web.xml中扫描的包列表中来解决的。您只有
com.mkyong.rest
,它不包括您需要的提供者。可以使用逗号分隔符添加多个包