自定义注释注射新泽西州的1.x [英] Custom annotation injection with Jersey 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 anInjectable
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 theusername
andpassword
, 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 thegetInjectable
, then pass that value onto theBasicAuthInjectable
. 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 theUser
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屋!