簡體   English   中英

如何啟動 jax-rs 服務器?

[英]How to start a jax-rs server?

我有這樣的端點:

@Path("/users")
public class Users {
    private final SomeDependency dependency

    public Users(SomeDependency dependency) {
        this.dependency = dependency;
    }

    @GET
    @Path("/{id}")
    public Response Get(@PathParam("id") int id) {
        User user = this.dependency.get(id);
        return Response.ok(user).build();
    }
}

現在我如何使用這個端點實際運行服務器?

我對 web 服務器/應用程序/servlet 感到困惑,使用 jersey jetty glassfish 或其他。 還有 web.xml 個文件? 什么? ResourceConfigs 只接受類,不接受它們的實例。 一切似乎都是那么一團糟。

我怎么能做類似的事情呢?

public static void main(String[] args) throws Exception {
        SomeDependency dependency = new SomeDependency();
        Users usersEndpoint = new Users(dependency);
        
        Server server = new Server();
        server.registerEndpoint(usersEndpoint);
        server.start();
}

服務器

就服務器而言,您必須考慮兩種類型:安裝或嵌入式。

已安裝

安裝的服務器是安裝在您的機器上的服務器。 例如,如果您下載 Tomcat 10然后按照安裝說明進行操作,服務器將安裝在您選擇的任何位置的機器上。 在這種情況下,當您有一個准備好部署的應用程序(一個 war 文件)時,您將把它復制到您的 Tomcat 服務器(到一個特定位置)並且在服務器啟動時,Tomcat 將看到該應用程序然后運行它。 在此類環境中運行的應用程序將需要 web.xml,因為它們部署在 war 文件中。

嵌入式

嵌入式服務器是一種打包到您的 jar 應用程序中並像任何其他 Java SE 應用程序一樣以main方法啟動的服務器。 大多數已安裝的服務器還帶有嵌入式版本。 您需要做的就是將服務器依賴項添加到您的應用程序中,然后編寫服務器配置和啟動(和關閉)代碼。 在此環境中運行的應用程序不需要 web.xml,因為它們被部署為 jar 文件。

使用哪一個?

隨着雲服務和微服務的進步和普及,許多應用程序正在向嵌入式服務器遷移。 原因是它們易於部署、可擴展、相對輕量級,並且應用程序變得更加獨立。 使用嵌入式服務器還有許多其他優點,但也有一些缺點。 在做出最終決定應該使用哪一個之前,請先進行研究。

例子

如果您想快速開始而不必擔心設置項目、知道需要添加哪些依賴項、添加啟動代碼,啟動和運行的簡單方法是使用 Maven Archetype。 如果您 go 訪問Jersey 文檔,他們會幫助您開始使用運行 Jersey 應用程序的嵌入式Grizzly 服務器。 您需要做的是從命令行運行以下命令(假設您的機器上安裝了 Maven)

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
  -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
  -DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
  -DarchetypeVersion=2.33

如果您閱讀我鏈接到的文檔,它會解釋初始應用程序附帶的所有內容。 主要的 class 將如下所示(省略注釋和導入)

public class Main {

    public static final String BASE_URI = "http://localhost:8080/myapp/";

    public static HttpServer startServer() {

        final ResourceConfig rc = new ResourceConfig().packages("org.example");

        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}

在這段代碼中,他們使用ResourceConfig class 的packages()方法為 Jersey 指定一個 package 來掃描要注冊的@Path@Provider類。 在你的情況下,如果你不需要它,你可以刪除方法調用。 如果你想注冊你的 Users 實例,你所做的就是在ResourceConfig上調用register(users)

也可以看看

其他框架

您可能還需要考慮其他框架

  • Dropwizard -Dropwizard 是一個建立在 Jersey 之上的自以為是的框架。它使用嵌入式 Jetty 作為其服務器,並具有許多其他功能,可以使您的應用程序開發更加輕松. 他們有很好的、易於理解的文檔。 如果您想嘗試一下,有一個很好的“入門”指南。

  • Spring Boot - Spring Boot 是一個引導框架,可以更輕松地啟動和運行應用程序。 有為您制作的自動配置,但您可以選擇更改它們。 在使用 Spring Boot 時,您可以使用 Spring MVC 或 Jersey 作為 REST 框架。 還有一個Initializer ,它類似於 Maven Archetypes,但它是交互式的,允許您向應用程序添加您想要的內容。

所以我只是接受了 java 是一團糟的事實,並將這些依賴項拉入:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    <version>3.4.2</version>
</dependency>
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-jetty</artifactId>
    <version>3.4.2</version>
</dependency>

所以我可以像這樣啟動一切:

public static void main(String[] args) throws Exception {
    SomeDependency dependency = new SomeDependency();
    Users usersEndpoint = new Users(dependency);
    
    JAXRSServerFactoryBean serverFactory = new JAXRSServerFactoryBean();

    serverFactory.setResourceClasses(usersEndpoint.getClass());
    serverFactory.setResourceProvider(usersEndpoint.getClass(), new SingletonResourceProvider(usersEndpoint));

    serverFactory.setAddress("http://localhost:8080/");
    serverFactory.create().start();
}

當然,我有更多端點,所以我將所有內容都放在一個 for 循環中。

至於我為什么要用訪客賬號回答,我問這個問題的賬號是用一個一次性的email地址創建的,我現在不能訪問了。

希望這對將來的任何人都有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM