dav*_*vid 2 java jersey jersey-2.0
我意识到这些是内部API,但是如果内部可以使用它们,为什么不让特权较低的人群使用它们,它们也非常有用。即使这些API在Jersey 2.25中是内部的,也可以使用,并且我想在不破坏自定义Jersey扩展的情况下升级Jersey版本。
当然可以ValueParamProvider在Jersey 2.27中进行扩展,但是我再也看不到一种注册该Provider及其触发注释的方法。查看Jersey如何针对自己的实现执行此操作,现在使用BoostrapConfigurator,它似乎已被内部化,以至于外部实现无法使用相同的方法。
也许我对此有误,如果有人对方法有清晰的描述,那就太好了。否则,有人知道做相同事情的方法吗?
这曾经工作...
ResourceConfig resourcceConfig = ...
resourceConfig.register(new AbstractBinder() {
@Override
protected void configure (){
bind(MyParamValueFactoryProvider.class).to(ValueFactoryProvider.class).in(Singleton.class);
bind(MyParamInjectionResolver.class).to(new TypeLiteral<InjectionResolver<EntityParam>>() {
}).in(Singleton.class);
}
}
});
Run Code Online (Sandbox Code Playgroud)
有了适当的实现AbstractValueFactoryProvider和ParamInjectionResolver。
现在看来您需要实现ValueParamProvider,这很容易,但是我不确定如何再使用Jersey框架正确进行注册。任何帮助表示赞赏。
您无需使用任何BootstrapConfigurator。您需要做的就是将服务添加到注射器中,稍后将添加它们到值提供者列表中。
要配置它,您仍然可以使用AbstractBinder,但可以使用Jersey 1代替HK2 。将ValueParamProvider仍然可以绑定同样的方式,但对于InjectionResolver,你应该确保实现不HK2解析器,但新泽西州一个。然后,而不是结合TypeLiteral,结合GenericType。
我只是想补充一点,人们在尝试实现参数注入时存在一个误解,就是我们还需要InjectResolver为方法参数使用自定义注释。不是这种情况。方法参数注释只是我们应在ValueParamProvider#getValueProvider()方法内部检查的标记注释。InjectResolver仅对于非方法参数注入(例如,字段和构造函数注入)才需要An 。如果不需要,则不需要InjectionResolver。
以下是使用Jersey测试框架的完整示例。我没有使用InjectionResolver,只是为了表明它不是必需的。
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.Response;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.assertThat;
public class ParamInjectTest extends JerseyTest {
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
}
private static class User {
private String username;
public User(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
}
public static class AuthValueParamProvider implements ValueParamProvider {
@Override
public Function<ContainerRequest, ?> getValueProvider(Parameter parameter) {
if (parameter.getRawType().equals(User.class)
&& parameter.isAnnotationPresent(Auth.class)) {
return new UserParamProvider();
}
return null;
}
private class UserParamProvider implements Function<ContainerRequest, User> {
@Override
public User apply(ContainerRequest containerRequest) {
return new User("Peeskillet");
}
}
@Override
public PriorityType getPriority() {
return Priority.HIGH;
}
}
public static class AuthFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder() {
@Override
protected void configure() {
bind(AuthValueParamProvider.class)
.to(ValueParamProvider.class)
.in(Singleton.class);
}
});
return true;
}
}
@Path("test")
@Consumes("text/plain")
public static class TestResource {
@POST
@Produces("text/plain")
public Response post(String text, @Auth User user) {
return Response.ok(user.getUsername() + ":" + text).build();
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig()
.register(TestResource.class)
.register(AuthFeature.class);
}
@Test
public void testIt() {
final Response response = target("test")
.request()
.post(Entity.text("Test"));
assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.readEntity(String.class)).isEqualTo("Peeskillet:Test");
}
}
Run Code Online (Sandbox Code Playgroud)
我还要提到的另一件事是,在以前的版本中,您扩展AbstractValueFactoryProvider并实现了a ParamInjectionResolver,大多数人这样做是为了遵循Jersey如何实现参数注入,同时仍然允许其他注入点(字段和构造函数)。如果您仍想使用此模式,则可以。
下面是AuthFeature从以上测试重构而成的
public static class AuthFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
InjectionManager im = InjectionManagerProvider.getInjectionManager(context);
AuthValueParamProvider authProvider = new AuthValueParamProvider();
im.register(Bindings.service(authProvider).to(ValueParamProvider.class));
Provider<ContainerRequest> request = () -> {
RequestProcessingContextReference reference = im.getInstance(RequestProcessingContextReference.class);
return reference.get().request();
};
im.register(Bindings.injectionResolver(new ParamInjectionResolver<>(authProvider, Auth.class, request)));
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我只是从源头中找出这些东西。我在中看到的所有这些配置ValueParamProviderConfigurator。您无需实现自己的ParamInjectionResolver。正如上面的功能所做的那样,Jersey已经有一个我们可以使用的具体类。
如果您TestResource将字段更改为注入,它现在应该可以使用
@Path("test")
@Consumes("text/plain")
public static class TestResource {
@Auth User user;
@POST
@Produces("text/plain")
public Response post(String text) {
return Response.ok(user.getUsername() + ":" + text).build();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |