Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
361 views
in Technique[技术] by (71.8m points)

java - Jersey 2.26: register @Inject in ResourceConfig bindFactory cannot convert Factory to Supplier

I'm now using Jersey and I want to Inject a GeneralForm map into the Resource class context, which accepts all application/json, multipart/form-data and application/x-www-form-urlencoded format submits.

I follow the instructions specified under the Jersey documentation:

https://jersey.github.io/documentation/latest/ioc.html#d0e17033

GeneralForm.java

package cn.easecloud.jrf.provider;
import java.util.HashMap;

public class GeneralForm extends HashMap<String, Object> {
}

GeneralFormFactory.java

package cn.easecloud.jrf.provider;

import org.glassfish.hk2.api.Factory;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

public class GeneralFormFactory implements Factory<GeneralForm> {

    private final HttpServletRequest request;

    @Inject
    public GeneralFormFactory(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public GeneralForm provide() {
        GeneralForm result = new GeneralForm();
        return result;
    }

    @Override
    public void dispose(GeneralForm t) {
    }

}

And then I register that Factory into my ResouceConfig:

package cn.cwhale.bowei;

import cn.easecloud.jrf.provider.AuthenticationFilter;
import cn.easecloud.jrf.provider.GeneralForm;
import cn.easecloud.jrf.provider.GeneralFormFactory;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spring.SpringLifecycleListener;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
import org.springframework.web.filter.CommonsRequestLoggingFilter;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.container.ContainerRequestFilter;

@ApplicationPath("/api/*")
public class AppConfig extends ResourceConfig {

    public AppConfig() {

        packages("cn.cwhale.bowei");

        register(MultiPartFeature.class);
        register(SpringLifecycleListener.class);
        register(RequestContextFilter.class);
        register(ContainerRequestFilter.class);
        register(CommonsRequestLoggingFilter.class);
        register(AuthenticationFilter.class);

        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(GeneralFormFactory.class).to(GeneralForm.class)
                .proxy(true).proxyForSameScope(false).in(RequestScoped.class);
            }
        });

        property("encoding", "utf-8");

    }

}

But then I failed because the bindFactory method accepts a Supplier<T> argument which the Factory class did not implemented.

enter image description here

And when compile:

方法 org.glassfish.jersey.internal.inject.AbstractBinder.<T>bindFactory(java.lang.Class<? extends java.util.function.Supplier<T>>,java.lang.Class<? extends java.lang.annotation.Annotation>)不适用
  (无法推断类型变量 T
    (实际参数列表和形式参数列表长度不同))
方法 org.glassfish.jersey.internal.inject.AbstractBinder.<T>bindFactory(java.lang.Class<? extends java.util.function.Supplier<T>>)不适用
  (无法推断类型变量 T
    (参数不匹配; java.lang.Class<cn.easecloud.jrf.provider.GeneralFormFactory>无法转换为java.lang.Class<? extends java.util.function.Supplier<T>>))
方法 org.glassfish.jersey.internal.inject.AbstractBinder.<T>bindFactory(java.util.function.Supplier<T>)不适用
  (无法推断类型变量 T
    (参数不匹配; java.lang.Class<cn.easecloud.jrf.provider.GeneralFormFactory>无法转换为java.util.function.Supplier<T>))
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Jersey 2.26 made some changes to its DI support. First it removed HK2 as a hard dependency and added an abstraction layer. The new framework uses some of the names from HK2 but the packaging is different. For instance the AbstractBinder. You can see in your code, that there is no hk2 in the package name. This is the new abstraction layer Jersey uses.

The new layer makes a lot of use of Java 8. For instance with the bindFactory, it no longer uses the HK2 Factory, but instead uses the Java 8 Supplier. For for bindFactory you would now make your factory implement Supplier

public class GeneralFormFactory implements Supplier<GeneralForm> {

    private final HttpServletRequest request;

    @Inject
    public GeneralFormFactory(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public GeneralForm get() {
        GeneralForm result = new GeneralForm();
        return result;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...