Jersey:注入共享对象不适用于 Jetty
Jersey: Injecting of shared object not working with Jetty
我们想在 Jetty 上实现一个 REST 服务,它从多个客户端接收心跳,这些心跳存储在哈希图中,以便在进一步的功能中与它们一起工作。
这就是代码目前的样子:
应该注入的class。
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>();
}
...
}
活页夹class:
public class SharedMemoryBinder extends AbstractBinder{
@Override
protected void configure() {
bind(new SharedMemory()).to(SharedMemory.class);
}
}
特征class:
public class SharedMemoryFeature implements Feature{
@Override
public boolean configure(FeatureContext context) {
context.register(new SharedMemoryBinder());
return true;
}
}
服务class
@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();
}
...
}
申请class:
@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>
因此,使用此配置,当我 post 向 post 心跳服务发出心跳时,我总是会收到 415 不受支持的媒体类型异常,即使使用其他媒体类型也是如此。
"...i always get a 415 unsupported media type exception when i post"
这似乎不是与您的 DI 配置相关的问题。看起来您只需要注册 JSON 提供商。使用此特定提供商
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.3</version>
</dependency>
如果您通过 class 路径扫描覆盖 resources/provider 的注册(您已经完成,只需覆盖 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
class(扩展 Application
)。它更容易使用。
@ApplicationPath("/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("scan.packages.for.resource.and.provider");
register(ResourceOrProvider.class);
register(new MyAppBinder());
}
}
我们想在 Jetty 上实现一个 REST 服务,它从多个客户端接收心跳,这些心跳存储在哈希图中,以便在进一步的功能中与它们一起工作。
这就是代码目前的样子:
应该注入的class。
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>();
}
...
}
活页夹class:
public class SharedMemoryBinder extends AbstractBinder{
@Override
protected void configure() {
bind(new SharedMemory()).to(SharedMemory.class);
}
}
特征class:
public class SharedMemoryFeature implements Feature{
@Override
public boolean configure(FeatureContext context) {
context.register(new SharedMemoryBinder());
return true;
}
}
服务class
@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();
}
...
}
申请class:
@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>
因此,使用此配置,当我 post 向 post 心跳服务发出心跳时,我总是会收到 415 不受支持的媒体类型异常,即使使用其他媒体类型也是如此。
"...i always get a 415 unsupported media type exception when i post"
这似乎不是与您的 DI 配置相关的问题。看起来您只需要注册 JSON 提供商。使用此特定提供商
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.3</version>
</dependency>
如果您通过 class 路径扫描覆盖 resources/provider 的注册(您已经完成,只需覆盖 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
class(扩展 Application
)。它更容易使用。
@ApplicationPath("/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("scan.packages.for.resource.and.provider");
register(ResourceOrProvider.class);
register(new MyAppBinder());
}
}