使用 Jersey 1.x 自定义注解注入
Custom annotation injection with Jersey 1.x
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 版本作为休息 api。在那个生命周期中我必须在哪里编辑 class?
@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
to support the custom injection, and also an Injectable
来提供值。
这是一个例子
@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]);
}
}
你会注意到我有一个 User
class。这是把username
和password
包裹起来,只有一个注入点。即
public Response getSomething(@BasicAuth User user) {
}
我实际上试着按照你的方式去做,
public Response getSomething(@BasicAuth("username") String username,
@BasicAuth("password") String password) {
并在 InjectableProvider
中从传递给 getInjectable
的注释中获取注释值,然后将该值传递给 BasicAuthInjectable
。从那里检查值是否为 "username"
或 "password"
和 return 对应的值。但出于某种原因,注入提供者甚至没有被调用。您可以尝试一下,看看是否可以正常工作。但对我来说 User
看起来更干净了,并且对于两个字符串,注入提供程序被调用两次,你需要解析 headers 两次。好像没必要。
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 版本作为休息 api。在那个生命周期中我必须在哪里编辑 class?
@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
to support the custom injection, and also an Injectable
来提供值。
这是一个例子
@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]);
}
}
你会注意到我有一个 User
class。这是把username
和password
包裹起来,只有一个注入点。即
public Response getSomething(@BasicAuth User user) {
}
我实际上试着按照你的方式去做,
public Response getSomething(@BasicAuth("username") String username,
@BasicAuth("password") String password) {
并在 InjectableProvider
中从传递给 getInjectable
的注释中获取注释值,然后将该值传递给 BasicAuthInjectable
。从那里检查值是否为 "username"
或 "password"
和 return 对应的值。但出于某种原因,注入提供者甚至没有被调用。您可以尝试一下,看看是否可以正常工作。但对我来说 User
看起来更干净了,并且对于两个字符串,注入提供程序被调用两次,你需要解析 headers 两次。好像没必要。