Jersey 1.x 自定义注解注入 [英] Custom annotation injection with 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
类.这是为了包装username
和password
,只有一个注入点.即
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屋!