自定义注释注射新泽西州的1.x [英] Custom annotation injection with Jersey 1.x

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

问题描述


  

我使用的球衣1.9.1。我有一个像下面的地方休息方法
  授权头包含连接codeD的凭据,如用户名
  和密码,它被解析中的方法和映射的本地值


  @PUT
@Path(SystemConstants.REST_MESSAGE_SENDSMS)
@Consumes(MediaType.APPLICATION_JSON)
@Produces({} MediaType.APPLICATION_JSON)
市民反应sendSms(@HeaderParam(授权)授权的字符串,字符串参数){    的String [] =凭证ImosUtils.getUserCredentials(授权);
    字符串username =凭据[0];
    字符串密码=凭证[1];
    }

我试图设计一种能够自动让这个过程,无需在每个方法编写相同的解析code。我的意思是,我想知道,如果写一个特殊的注解,如 HeaderParamExtended 这个是用来解析这个凭据。结果
我使用的球衣1.9.1版本REST API。在那里我有在生命周期编辑类?

  @PUT
@Path(SystemConstants.REST_MESSAGE_SENDSMS)
@Consumes(MediaType.APPLICATION_JSON)
@Produces({} MediaType.APPLICATION_JSON)
市民反应sendSms(@HeaderParamExtended(授权,用户名)字符串的用户名,@HeaderParamExtended(授权,密码)字符串密码,字符串参数){
    }


解决方案

通常你需要的 InjectableProvider 以支持自定义的注入,还一个的 注射 提供价值。

下面是一个例子

@BasicAuth

  @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
公共@interface基本验证{
}

InjectableProvider

  @Provider
公共类BasicAuthInjectionProvider
        实现InjectableProvider<基本验证,参数> {    @覆盖
    公共ComponentScope getScope(){
        返回ComponentScope.PerRequest;
    }    @覆盖
    公共注射getInjectable(ComponentContext毫升,基本验证一个,参数c){
        返回新BasicAuthInjectable();
    }
}

注射

 公共类BasicAuthInjectable扩展AbstractHttpContextInjectable<使用者> {    @覆盖
    公共用户的getValue(HttpContext的HC){
        字符串authHeaderValue = hc.getRequest()
                .getHeaderValue(HttpHeaders.AUTHORIZATION);
        的String [] =凭证ImosUtils.getUserCredentials(authHeaderValue);        返回新用户(证书[0],凭据[1]);
    }
}

有一件事你会注意到的是,我有一个用户类。这是包裹用户名密码,只是有一个注射点。即。

 公开回应getSomething(@BasicAuth用户用户){
}

其实,我试图做你的方式,以

 公开回应getSomething(@BasicAuth(用户名)字符串的用户名,
                             @BasicAuth(密码)字符串密码){

而在 InjectableProvider 得到传递到 getInjectable 注释标注值,然后将该值传递到在 BasicAuthInjectable 。从那里检查,看看是否值为用户名密码,并返回相应的值。但由于某些原因,注射供应商甚至没有叫。你可以玩它,看看你能得到它的工作。但对我的用户看起来比较清爽,无论如何,和这两个字符串,注射提供商调用两次,你需要分析的头两次。似乎没有必要。

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];       
    }

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


    }

解决方案

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

Here's an example

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

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

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.

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

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