Jersey 1.x 自定义注解注入 [英] Custom annotation injection with Jersey 1.x

查看:32
本文介绍了Jersey 1.x 自定义注解注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是球衣 1.9.1.我有如下休息方法授权标头包含编码的凭据,例如用户名和密码,并在方法中解析并映射本地值.

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 版本作为 rest api.在那个生命周期中我必须在哪里编辑一个类?

I am trying to design a way to make this process automatically, without writing same parsing code in each method. I mean I would like to know if writing a special annotation such as HeaderParamExtended to this is used to parse this credentials.
I am using jersey 1.9.1 version as rest api. Where I have to edit a class in that life cycle?

@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 支持自定义注入,还有一个 Injectable 提供值.

Normally you need an InjectableProvider to support the custom injection, and also an Injectable to provide the value.

这是一个例子

@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();
    }
}

可注射

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 类.这是为了包装usernamepassword,只有一个注入点.即

One thing you'll notice is that I have a User class. This is to wrap the username and password, and just have one injection point. i.e.

public Response getSomething(@BasicAuth User user) {
}

我实际上是按照你的方式来做的,

I actually tried to do it your way, with

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

并在 InjectableProvider 中从传递给 getInjectable 的注释中获取注释值,然后将该值传递给 BasicAuthInjectable.从那里检查值是 "username" 还是 "password" 并返回相应的值.但出于某种原因,甚至没有调用注入提供者.你可以玩弄它,看看你是否可以让它工作.但对我来说 User 无论如何看起来更干净,并且使用两个字符串,注入提供程序被调用两次,您需要解析标题两次.似乎没有必要.

And in the InjectableProvider get the annotation value from the annotation passed to the getInjectable, then pass that value onto the BasicAuthInjectable. From there check to see if the value is "username" or "password" and return the corresponding value. But for some reason the injection providers were not even called. You can play around with it to see if you can get it to work. But to me the User looks cleaner anyway, and with the two strings, the injection providers are called twice and you need to parse the headers twice. Seems unnecessary.

这篇关于Jersey 1.x 自定义注解注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆