REST Web 服务 - 如何像单例一样使用服务?
REST WebServise - how to use service like a singleton?
我的其余应用程序包含一个服务,我需要使该服务像单例一样运行以保存服务的状态。
一项服务:
@Path("/script")
public class ScriptEngineProvider {
private AtomicInteger idCounter;
public ScriptEngineProvider() {
System.out.println("before AtomicInteger");
idCounter = new AtomicInteger();
}
@POST
public Response executeScript( String x ) {
idCounter.incrementAndGet();
System.out.println("counter " + idCounter);
...
除所有其他代码外,客户端还具有:
WebTarget webTarget = client.target("http://localhost:8080/NashornEngine/rest").path("script");
web.xml
<url-pattern>/rest/*</url-pattern>
通过上述配置,应用程序可以正常工作,但每个请求都会创建变量 idCounter
,因此 idCounter
总是 1
.
现在我使用 next class 使 ScriptEngineProvider
成为单例:
@ApplicationPath("/services")
public class NashornApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public NashornApplication() {
singletons.add(new ScriptEngineProvider());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
问题是我得到 The requested resource is not available
请求:
//path services was added
WebTarget webTarget = client.target("http://localhost:8080/NashornEngine/rest").path("services").path("script");
这个配置有什么问题?
试试这个:
@Singleton // this is the important line
@Path("/script")
public class ScriptEngineProvider {
private AtomicInteger idCounter;
public ScriptEngineProvider() {
System.out.println("before AtomicInteger");
idCounter = new AtomicInteger();
}
@POST
public Response executeScript( String x ) {
idCounter.incrementAndGet();
System.out.println("counter " + idCounter);
...
@ApplicationPath
实际上与 url-mapping
的目的相同。但是只能用一个。当您不想使用 web.xml 配置时,可以将 @ApplicationPath
与 Application
subclass 一起使用。要上网。xml-less,您需要确定两件事
- 您正在部署到 3.x servlet 容器。
您拥有支持 servlet 可插入性的依赖项。查看更多
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
也可以使用 Application
subclass 没有 @ApplicationPath
,然后将使用 url-mapping
映射 Jersey servlet。例如
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.pkg.YourApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
无论您选择哪种方式,都会使用 url-mapping
路径或 @ApplicationPath
值,但不会同时使用两者。因此,在您的情况下,如果您不使用 web.xml 配置,则路径将不包括 url-mapping
中的 /rest
。如果你使用上面的 web.xml 配置,那么你应该去掉 Application
subclass 上的 @ApplicationPath
,你会使用 url有 /rest
,没有 /services
.
你一直得到一个的原因是
- 默认行为是为每个请求创建一个新资源class
- 你的
Application
子class没有被使用,你的web.xml配置正在被使用,你正在包扫描。
查看此 post 中的信息并进行相应的更改。
我的其余应用程序包含一个服务,我需要使该服务像单例一样运行以保存服务的状态。
一项服务:
@Path("/script")
public class ScriptEngineProvider {
private AtomicInteger idCounter;
public ScriptEngineProvider() {
System.out.println("before AtomicInteger");
idCounter = new AtomicInteger();
}
@POST
public Response executeScript( String x ) {
idCounter.incrementAndGet();
System.out.println("counter " + idCounter);
...
除所有其他代码外,客户端还具有:
WebTarget webTarget = client.target("http://localhost:8080/NashornEngine/rest").path("script");
web.xml
<url-pattern>/rest/*</url-pattern>
通过上述配置,应用程序可以正常工作,但每个请求都会创建变量 idCounter
,因此 idCounter
总是 1
.
现在我使用 next class 使 ScriptEngineProvider
成为单例:
@ApplicationPath("/services")
public class NashornApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public NashornApplication() {
singletons.add(new ScriptEngineProvider());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}
问题是我得到 The requested resource is not available
请求:
//path services was added
WebTarget webTarget = client.target("http://localhost:8080/NashornEngine/rest").path("services").path("script");
这个配置有什么问题?
试试这个:
@Singleton // this is the important line
@Path("/script")
public class ScriptEngineProvider {
private AtomicInteger idCounter;
public ScriptEngineProvider() {
System.out.println("before AtomicInteger");
idCounter = new AtomicInteger();
}
@POST
public Response executeScript( String x ) {
idCounter.incrementAndGet();
System.out.println("counter " + idCounter);
...
@ApplicationPath
实际上与 url-mapping
的目的相同。但是只能用一个。当您不想使用 web.xml 配置时,可以将 @ApplicationPath
与 Application
subclass 一起使用。要上网。xml-less,您需要确定两件事
- 您正在部署到 3.x servlet 容器。
您拥有支持 servlet 可插入性的依赖项。查看更多
<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>${jersey2.version}</version> </dependency>
也可以使用 Application
subclass 没有 @ApplicationPath
,然后将使用 url-mapping
映射 Jersey servlet。例如
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.pkg.YourApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
无论您选择哪种方式,都会使用 url-mapping
路径或 @ApplicationPath
值,但不会同时使用两者。因此,在您的情况下,如果您不使用 web.xml 配置,则路径将不包括 url-mapping
中的 /rest
。如果你使用上面的 web.xml 配置,那么你应该去掉 Application
subclass 上的 @ApplicationPath
,你会使用 url有 /rest
,没有 /services
.
你一直得到一个的原因是
- 默认行为是为每个请求创建一个新资源class
- 你的
Application
子class没有被使用,你的web.xml配置正在被使用,你正在包扫描。
查看此 post 中的信息并进行相应的更改。