从头开始没有任何以前的Jersey 1.x知识,我很难理解如何在我的Jersey 2.0项目中设置依赖注入.
我也明白HK2可用于Jersey 2.0,但我似乎无法找到有助于Jersey 2.0集成的文档.
@ManagedBean
@Path("myresource")
public class MyResource {
@Inject
MyService myService;
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/getit")
public String getIt() {
return "Got it {" + myService + "}";
}
}
@Resource
@ManagedBean
public class MyService {
void serviceCall() {
System.out.print("Service calls");
}
}
Run Code Online (Sandbox Code Playgroud)
的pom.xml …
对于我工作的一些项目,我最近从Jersey 1换到了Jersey 2.我遇到过泽西2号的最大烦恼是它使用的是HK2,由于某种原因重新打包标准的Maven文物.为了避免潜在的讨厌调试问题,我尽量避免从不同的项目中引入相同的类.我使用Extra Enforcer规则依赖项中的Ban Duplicate Classes Maven强制执行规则来破坏构建(如果发生这种情况).
根据前面提到的Ban Duplicate Classes enforcer规则,切换到Jersey 2会在其工件和我之前使用的标准工件之间引入以下冲突:
hk2 Artifact Conflicting Artifact
org.glassfish.hk2.external:aopalliance-repackaged:2.3.0-b07 aopalliance:aopalliance:1.0
org.glassfish.hk2.external:bean-validator:2.3.0-b07 com.fasterxml:classmate:0.8.0 (used by org.hibernate:hibernate-validator:5.0.0.Final)
org.glassfish.hk2.external:bean-validator:2.3.0-b07 javax.validation:validation-api:1.1.0.Final
org.glassfish.hk2.external:bean-validator:2.3.0-b07 org.hibernate:hibernate-validator:5.0.0.Final
org.glassfish.hk2.external:bean-validator:2.3.0-b07 org.jboss.logging:jboss-logging:3.1.0.GA
org.glassfish.hk2.external:javax.inject:2.3.0-b07 javax.inject:javax.inject:1
Run Code Online (Sandbox Code Playgroud)
我的解决方案是将标准工件从可传递的依赖项中排除,因此只使用hk2工件.我认为这更安全:我不知道hk2工件还有什么东西可能会丢失,如果我要排除它们(例如,bean-validator工件似乎重新打包至少四个工件).这样做的缺点是,首先,我对我的依赖项进行了大量的排除,这些依赖项带来了其他无关紧要的API依赖项,例如validation-api.其次,我的工件现在正在导出HK2重新打包的依赖项,而不是我希望导出的实际API类.
最终,我的问题是:
除了这些问题的实际答案之外,联系HK2背后的开发人员会有什么好的论坛,所以我可以直接提出这个问题?我查看了网站,虽然我找到了一些邮件列表,但我没有看到任何明显适合提问的问题.
我无法使用Jersey 2(2.7)和Jersey内置的HK2依赖注入来实现一个非常基本的单例类实现.我在Tomcat上运行它.
我的目标是创建将由各种Web服务方法使用的支持类的单例实例.我没有强烈的偏好在构造函数注入,方法注入和注释类成员之间(如下所示).
这是我要成为的单身人士课程:
package singletest;
import javax.inject.Singleton;
@Singleton
public class JustOne {
private int secretNumber = 0;
public void hitMe(int input) {
secretNumber += input;
}
@Override
public String toString() {
return String.format("{ \"secretNumber\": %s }", secretNumber);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的应用程序类:
package singletest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
@ApplicationPath("/*")
public class MainApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(TestResource.class);
return classes;
}
@Override
public Set<Object> getSingletons() {
Set<Object> singletons = …
Run Code Online (Sandbox Code Playgroud) 在Jersey Rest应用程序中使用DI时出错:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=PricingService,parent=PricingResource,qualifiers={},position=0,optional=false,self=false,unqualified=null,1633188703)
Run Code Online (Sandbox Code Playgroud)
我对这个概念很陌生,看起来很复杂,因为有些例子似乎已被弃用了.据我所知,有几种方法可以使DI工作:原生HK2,Spring/HK2 Bridge.什么是更简单,更直接的配置?如何为Jersey 2.x以编程方式(而不是XML的粉丝)进行设置?
ResourceConfig
import org.glassfish.jersey.server.ResourceConfig;
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(new ApplicationBinder());
packages(true, "api");
}
}
Run Code Online (Sandbox Code Playgroud)
AbstractBinder
public class ApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(PricingService.class).to(PricingService.class).in(Singleton.class);
}
}
Run Code Online (Sandbox Code Playgroud)
PricingResource
@Path("/prices")
public class PricingResource {
private final PricingService pricingService;
@Inject
public PricingResource(PricingService pricingService) {
this.pricingService = pricingService;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<Price> findPrices() {
return pricingService.findPrices();
}
}
Run Code Online (Sandbox Code Playgroud)
PricingService
@Singleton
public …
Run Code Online (Sandbox Code Playgroud) 这可能是一个愚蠢的问题,但我很困惑,我无法在任何地方找到任何明确的解释.
HK2是一个实现JS330的依赖注入框架,它是Glassfish V3和V4的基础.据我所知,泽西岛使用它
Weld是CDI的参考实现,它也是一个依赖注入框架,也可以在Glassfish中使用?
所以我的问题是这些
我理解这些问题源于我对Java EE整个生态系统的微薄理解,但我们将非常感谢任何答案
我正在从DropWizard 0.7.1迁移到0.8.1.这包括从Jersey 1.x迁移到2.x. 在我使用Jersey 1.18.1的实现中,我实现了MyProvider
(为简单起见改变了所有类名)InjectableProvider
.该类将创建MyInjectable
包含自定义注入注释的对象MyToken
.MyToken
包含传递和读取的各种属性MyInjectable
.最后,在Application
类中我注册了一个新的实例MyProvider
,如下所示.
我做了一些研究,似乎无法解决我在泽西岛2.x中如何重新创建(或替代,我认为)这样一个场景.
这是当前的1.18.1实现:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.PARAMETER, ElementType.FIELD })
public @interface MyToken {
// Custom annotation containing various attributes
boolean someAttribute() default true;
// ...
}
public class MyProvider implements InjectableProvider<MyToken, Parameter> {
// io.dropwizard.auth.Authenticator
private final Authenticator<String, MyObject> authenticator;
public MyProvider(Authenticator<String, MyObject> authenticator) {
this.authenticator = authenticator;
}
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
@Override
public Injectable<?> getInjectable(ComponentContext …
Run Code Online (Sandbox Code Playgroud) 我们有一场战争,通过基于hibernate-4.2.7验证的验证(实现validation-api-1.0.0.GA),在场地2.6上展示休息服务.
在我们升级到java 8和tc-server 3.1.X之前,一切正常.
升级到java 8之后,看起来在验证API中出现了问题.
我们得到了
java.lang.NoSuchMethodError:javax.validation.Configuration.getBootstrapConfiguration()Ljavax/validation/BootstrapConfiguration;
当我们从客户端发送休息请求时.
最奇怪的是,这种行为并不构成
当我从依赖项添加或删除jar时,它有时会起作用,有时候不起作用.
我们得到以下例外
SEVERE [tomcat-http--1] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jerseyServlet] in context with path [/Analyzer] threw exception [A MultiException has 1 exceptions. They are:
1. java.lang.NoSuchMethodError: javax.validation.Configuration.getBootstrapConfiguration()Ljavax/validation/BootstrapConfiguration;
] with root cause
java.lang.NoSuchMethodError: javax.validation.Configuration.getBootstrapConfiguration()Ljavax/validation/BootstrapConfiguration;
at org.glassfish.jersey.server.validation.internal.ValidationBinder$ConfiguredValidatorProvider.getTraversableResolver(ValidationBinder.java:287)
at org.glassfish.jersey.server.validation.internal.ValidationBinder$ConfiguredValidatorProvider.getDefaultValidatorContext(ValidationBinder.java:268)
at org.glassfish.jersey.server.validation.internal.ValidationBinder$ConfiguredValidatorProvider.getDefaultValidator(ValidationBinder.java:248)
at org.glassfish.jersey.server.validation.internal.ValidationBinder$ConfiguredValidatorProvider.provide(ValidationBinder.java:199)
at org.glassfish.jersey.server.validation.internal.ValidationBinder$ConfiguredValidatorProvider.provide(ValidationBinder.java:173)
at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:96)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:69)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2445)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:621)
at org.jvnet.hk2.internal.IterableProviderImpl.get(IterableProviderImpl.java:107)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:135)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:406)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:350)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:106)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) …
Run Code Online (Sandbox Code Playgroud) 目前我正在开发基于运动衫的RESTful应用程序,并希望在我的资源中使用DPI.(注意:jersey的版本是2.23.1,servlet容器是tomcat 8.5.3.)
因此,我遵循了球衣文档中的第23章自定义注入和生命周期管理教程,并创建了一个资源,一个工厂,并将工厂绑定到这样的类:
资源:
@Path("/{project}/catalogs")
public class ProjectsResource {
@Inject
Project project;
...
}
Run Code Online (Sandbox Code Playgroud)
厂:
public class ProjectFactory extends Factory<Project> {
private final Cache cache = cache.getInstance();
@PathParam("project")
private String project;
private HttpServletRequest request;
@Inject
public ProjectFactory(HttpServletRequest request) {
this.request = request;
}
@Override
public Project provide() {
return cache.get(project, Project.class);
}
@Override
public void dispose(Project instance) {}
}
Run Code Online (Sandbox Code Playgroud)
我还有一个功能,它注册一个AbstractBinder,它将我的ProjectFactory绑定到我的Project类.
@Provider
public class ProjectFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder() {
@Override
protected …
Run Code Online (Sandbox Code Playgroud) 我有一个jersey2应用程序配置为通过杰克逊支持JSON,添加
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
在POM文件中
public MyApplication() {
...
register(JacksonFeature.class)
...
}
Run Code Online (Sandbox Code Playgroud)
在我的申请中.一切正常,我的资源将反序列化的POJO作为参数
@POST @Consumes(MediaType.APPLICATION_JSON)
public void blah(MyPojo p) {
...
}
Run Code Online (Sandbox Code Playgroud)
现在,其中一个资源需要提及杰克逊ObjectMapper
自己做一些反序列化.我试过做类似的事情
@Inject
public MyResource(@Context ObjectMapper mapper) {
...
}
Run Code Online (Sandbox Code Playgroud)
要么
@GET
public String foo(@Context ObjectMapper mapper) {
...
}
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下,引用都mapper
为null.如何ObjectMapper
在我的资源中注入引用?
我已经能够根据如何将对象注入到球衣请求上下文中从过滤器注入我的球衣资源?.这允许我成功注入方法参数:
@GET
public Response getTest(@Context MyObject myObject) { // this works
Run Code Online (Sandbox Code Playgroud)
但是,对于setter/field/constructor注入,HK2 Factory 在jersey过滤器之前调用,这意味着provide()方法返回null:
@Override
public MyObject provide() {
// returns null because the filter has not yet run,
// and the property has not yet been set
return (MyObject)context.getProperty("myObject");
}
Run Code Online (Sandbox Code Playgroud)
有没有办法定义何时运行HK2 Factory以便在过滤器运行后调用它?如果没有,则解决方法是将MyObject定义为接口,并定义在其构造函数中采用ContainerRequestContext的其他实现; 任何实际使用该实例的尝试都将懒惰地委托给在ContainerRequestContext属性上设置的实现(可能在过滤器运行之前你不会实际使用该实例 - 此时将设置该属性).
但我想了解是否有可能延迟HK2工厂运行的点,使其在过滤器之后运行(在方法参数注入的情况下,它已在过滤器之后运行).如果不可能,那么我想了解是否存在根本原因.
hk2 ×10
jersey-2.0 ×8
java ×7
jersey ×5
glassfish ×2
cdi ×1
dropwizard ×1
java-8 ×1
jax-rs ×1
json ×1
maven ×1
singleton ×1
validation ×1
weld ×1