Jersey框架:封装基于Jetty的通用服务器

1.需求场景

依赖于Jetty容器封装一个Jersey微服务的启动类,在微服务入口中通过简单的调用即可实现微服务启动。主要需求如下:

  • 可以指定服务启动端口
  • 可以指定服务的应用域路径
  • 可以指定要注册到Jersey容器的资源包
  • 可以指定要注册到Jersey容器的资源类

2.设计思路

  • 在通用封装类中维护一个Jetty的Server实例,代表真正的服务器
  • 默认注册res、filter和exception等资源包
  • 通过Jersey框架提供的ResourceConfig为服务器注册用户传入的资源
  • 提供不同的构造器,支持用户生成服务器实例时不同需求

设计类图如下:
Jersey框架:封装基于Jetty的通用服务器_第1张图片

3.代码实现

public class CommonServer {
     
    /**
     * 默认注册到Jersey容器的资源包
     */
    private String defaultPackageName = "org.bigdata.res," +
            "org.bigdata.filter," +
            "org.bigdata.exception";

    private Server server;

    class Application extends ResourceConfig {
     
        /**
         * @param packagesNames 要注册到Jersey容器的资源包,包之间以英文逗号隔开,
         *                      如org.bigdata.res,org.bigdata.res
         * @param classnames    要注册到Jersey容器的资源类,类使用完整类名,类之间以英文逗号隔开,
         *                      如org.bigdata.res.AppRes,org.bigdata.res2.UserRes
         */
        Application(String packagesNames, String classnames) {
     
            //默认注册工程下的res包
            packages(defaultPackageName);
            //默认注册文件上传下载支持类
            register(MultiPartFeature.class);
            if (StringUtils.isNotBlank(packagesNames)) {
     
                packages(packagesNames);
            }
            if (StringUtils.isNotBlank(classnames)) {
     
                for (String name : classnames.split(",")) {
     
                    try {
     
                        Class<?> clazz = Class.forName(name);
                        register(clazz);
                    } catch (ClassNotFoundException e) {
     
                        //如果找不到注册的类,则跳过不予注册
                    }
                }
            }
        }
    }

    public CommonServer(int port, String contextPath) {
     
        this.server = getServer(port, contextPath, null, null);
    }

    public CommonServer(int port, String contextPath, String packagesNames) {
     
        this.server = getServer(port, contextPath, packagesNames, null);
    }

    /**
     * 创建服务器
     *
     * @param port          服务端口
     * @param contextPath   应用域路径
     * @param packagesNames 要注册到Jersey容器的资源包
     * @param classnames    要注册到Jersey容器的资源类
     */
    public CommonServer(int port, String contextPath, String packagesNames, String classnames) {
     
        this.server = getServer(port, contextPath, packagesNames, classnames);
    }

    private Server getServer(int port, String contextPath, String packagesNames, String classnames) {
     
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(port);
        server.addConnector(connector);
        ServletContextHandler contextHandler = new ServletContextHandler();
        Application application = new Application(packagesNames, classnames);
        ServletContainer container = new ServletContainer(application);
        ServletHolder holder = new ServletHolder(container);

        contextHandler.addServlet(holder, "/*");
        contextHandler.setContextPath(contextPath);
        server.setHandler(contextHandler);

        HandlerList handlerList = new HandlerList();
        handlerList.addHandler(contextHandler);
        server.setHandler(handlerList);

        return server;
    }

    public void start() throws Exception {
     
        this.server.start();
    }

}

4.测试

4.1 新建测试资源类

在res2包下创建一下用于测试的TestRes资源类,代码如下:

package org.bigdata.res2;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/test")
public class TestRes {
     
    @GET
    public Response test() {
     
        return Response.ok("package res2 TestRes").build();
    }
}

4.2 服务启动

利用新封装的通用服务器类启动,指定端口、应用域路径和要注册的资源包,代码如下:

package org.bigdata;

import org.bigdata.common.CommonServer;

public class UserServer {
     

    public static void main(String[] args) throws Exception {
     
        CommonServer server = new CommonServer(8989, "/api/v1.0",
                "org.bigdata.res2");
        server.start();
    }
}

4.3 测试

启动微服务,控制台输出如下图。
Jersey框架:封装基于Jetty的通用服务器_第2张图片
在浏览器输入http://localhost:8989/api/v1.0/test,返回结果如下:
Jersey框架:封装基于Jetty的通用服务器_第3张图片

完整案例代码:https://github.com/majxbear/jetty-rest

你可能感兴趣的:(Jersey系列:实践全干货,Jersey,Jetty,通用,服务启动类,封装)