【问题标题】:Jersey: Injecting of shared object not working with Jetty泽西岛:注入共享对象不适用于 Jetty
【发布时间】:2015-05-08 07:34:15
【问题描述】:

我们想在 Jetty 上实现一个 REST 服务,它接收来自多个客户端的心跳,这些心跳存储在 Hashmap 中,以便在进一步的功能中与它们一起使用。

这就是代码现在的样子:

应该注入的类。

public class SharedMemory {

    private SharedMemory sharedMemory = null;
    private HashMap<String, HeartbeatModel> memory = null;
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock  = lock.readLock();
    private final Lock writeLock = lock.writeLock();

    public SharedMemory(){
        memory = new HashMap<String, HeartbeatModel>();
    }

    ...
}

活页夹类:

public class SharedMemoryBinder extends AbstractBinder{
        @Override
        protected void configure() {
            bind(new SharedMemory()).to(SharedMemory.class);
    }
}

要素类:

public class SharedMemoryFeature implements Feature{
    @Override
    public boolean configure(FeatureContext context) {
        context.register(new SharedMemoryBinder());
        return true;
     }
}

服务类

@Path("/HeartbeatService")
public class GCEHeartbeatService {

    @Inject
    private SharedMemory sharedMemory;

    @POST
    @Path("/postHeartbeat")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response postHeartbeat(Heartbeat heartbeat){
        sharedMemory.storeToMemory(heartbeat);

        return Response.ok().build();
    }
    ...
}

应用类:

@ApplicationPath("/")
public class Application extends javax.ws.rs.core.Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        classes.add(GCEHeartbeatService.class);
        classes.add(SharedMemoryFeature.class);
        return classes;
    }
}

这些是使用的依赖项:

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.17</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.4.1</version>
    </dependency>
    <dependency>
        <groupId>de.hszg</groupId>
        <artifactId>common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.bundles</groupId>
        <artifactId>jaxrs-ri</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.5.3</version>
    </dependency>
</dependencies>

因此,使用此配置,当我将心跳发布到 postHeartbeat 服务时,即使使用其他媒体类型,我总是会收到 415 不支持的媒体类型异常。

【问题讨论】:

    标签: java rest dependency-injection jersey-2.0


    【解决方案1】:

    “...我在发帖时总是收到 415 不支持的媒体类型异常”

    这似乎与您的 DI 配置无关。看起来您只需要注册 JSON 提供程序。使用这个特定的提供商

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.5.3</version>
    </dependency>
    

    如果您通过类路径扫描覆盖资源/提供者的注册(您已经这样做了,只需覆盖getClasses()并返回一个非空集,那么提供者将不会被注册。

    您可以简单地自己注册。

    classes.add(JacksonJsonProvider.class);
    -- or --
    classes.add(JacksonJaxbJsonProvider.class);
    

    如果您查看 jar,您还会看到一个您可能想要注册的 ExceptionMapper

    或者,您可以使用this dependency

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.17</version>
    </dependency>
    

    它将上述依赖项包装在自动发现功能中,并注册提供程序和ExceptionMapper。有了这个依赖,你就不需要注册任何东西了。如果由于某种奇怪的原因没有注册,您可以自己添加它

    classes.add(JacksonFeature.class);
    

    顺便说一句,如果可移植性不是问题,我会改用ResourceConfig 类(扩展Application)。使用起来要容易得多。

    @ApplicationPath("/")
    public class AppConfig extends ResourceConfig {
        public AppConfig() {
            packages("scan.packages.for.resource.and.provider");
            register(ResourceOrProvider.class);
            register(new MyAppBinder());
        }
    }
    

    ResourceConfig API

    【讨论】:

    • 感谢您的好回答,jacksonprovider 的缺失类是这种情况下的问题。我不知道被覆盖的 getClass 函数的影响。所以它现在工作正常。我会检查你的建议。
    猜你喜欢
    • 2011-12-30
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多