简体   繁体   中英

How to start a jax-rs server?

I have my endpoints like so:

@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();
    }
}

Now how do I actually run a server with this endpoint?

I am confused about web servers/applications/servlets, using jersey jetty glassfish or whatever. Also web.xml files? what? ResourceConfigs only accept classes, not their instances. Everything seems to be such a mess.

How can I just do something similar to this?

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();
}

Server

As far as the server goes, you have two types you have to consider: installed or embedded.

Installed

An installed server is one that is installed on your machine. For example, if you download Tomcat 10 and then follow the installation instruction , the server will get installed on your machine at whatever location you choose. In this situation, when you have an app (a war file) you are ready to deploy, you will copy it to your Tomcat server (to a specific location) and on server startup, Tomcat will see the application and then run it. The applications running in this type of environment will require a web.xml as they are deployed in a war file.

Embedded

An embedded server is one that is packaged into your jar application and is started in a main method just like any other Java SE application. Most installed servers also come with an embedded version. All you need to do is add the server dependencies into your application and then write the server configuration and startup (and shutdown) code. Applications running in this environment will not require a web.xml as they are deployed as a jar file.

Which one to use?

With the advancement and popularity of cloud services and microservices, many applications are moving towards embedded servers. The reason is that they are easy to deploy, are scalable, relatively lightweight, and applications become more self contained. There are many other pros that come with using embedded servers, but there are also some cons. Do your research before you make your final decision about which one you should use.

Example

If you want to quickly get started without having to worry about setting up the project, knowing what dependencies you need to add, adding the startup code, an easy way to get up and running is to use a Maven Archetype. If you go to the Jersey Docs , they get you started with an embedded Grizzly server running a Jersey application. What you need to do is run the following command from the command line (assuming you have Maven installed in your machine)

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

If you read the docs I linked to, it will give an explanation of all that comes with the initial application. The main class will look like the following (with comments and imports omitted)

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();
    }
}

In this code, they use the packages() method of the ResourceConfig class that specifies a package for Jersey to scan for @Path and @Provider classes to register. In your case, if you don't need that, you can remove the method call. If you want to register your Users instance, all you do is call register(users) on the ResourceConfig .

See Also

Other Frameworks

There are other frameworks out there that you may also want to consider

  • Dropwizard - Dropwizard is an opinionated framework built on top of Jersey. It uses an embedded Jetty as its server and comes with many other features to make developing your applications easier. They have pretty good, easy to follow documentation. There is a good "getting started" guide if you want to give them a try.

  • Spring Boot - Spring Boot is a bootstrapping framework that makes getting up and running with applications much easier. There are auto configurations made for you but give you options to change them. You can use Spring MVC or Jersey as the REST framework when you work with Spring Boot. There is also an Initializer , which is similar to the Maven Archetypes, but is interactive and allows you to add what you want to your applications.

So I just accepted the fact that java is an utter mess and pulled these dependencies in:

<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>

So i can launch everything like so:

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();
}

I have more endpoints, of course, so I put everything in a for loop.

As to why I'm answering from a guest account, the account I used to ask this question was created using a disposable email address, and I can no longer access it.

Hope this helps anyone in the future!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM