REST WebServise - 如何像单身一样使用服务?

时间:2016-01-03 14:53:59

标签: java web-services rest jax-rs jersey-2.0

我的休息应用程序包含一项服务,我需要使这项服务像单身人士一样保存服务状态。

服务:

@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

现在我使用下一个类使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");

此配置有什么问题?

2 个答案:

答案 0 :(得分:2)

试试这个:

@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);
    ...

答案 1 :(得分:1)

@ApplicationPath实际上与url-mapping具有相同的用途。但只能使用一种。当您不想使用web.xml配置时,可以将@ApplicationPathApplication子类一起使用。要使用web.xml-less,您需要确保两件事

  1. 您正在部署到3.x servlet容器。
  2. 您具有支持servlet可插拔性的依赖项。查看更多here

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey2.version}</version>
    </dependency>
    
  3. 也可以使用Application子类而不用 @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配置,则路径将不包括/rest中的url-mapping。如果你使用上面的web.xml配置,那么你应该摆脱@ApplicationPath子类上的Application,你将使用/rest的那个网址,而不是/services 1}}。

    你持续获得一个原因是因为

    1. 默认行为是为每个请求创建一个新的资源类
    2. 您的Application子类未被使用,并且正在使用您的web.xml配置,您正在进行包扫描。
    3. 查看此帖子中的信息,并相应地进行更改。