Jersey框架:利用ModelProcessor接口获取所有注册的资源

1.业务场景

1.1 业务需求

数据服务是数据治理的重要主题之一,目前流行的接口配置中心方案可以通过Jersey的Programming API实现,微服务启动时根据用户通过UI注册的资源路径进行服务动态注册,无需通过硬编码即可实现服务注册。

1.2 技术需求

Jersey的路径和请求方法唯一组成一个HTTP请求资源,Jersey微服务启动时,对所有注册的资源进行统计,方便后续用户在运行时注册资源时判断资源是否冲突。

2.设计思路

ModelProcessor是Jersey提供的扩展接口,用于对Jersey中注册的资源通过编程接口进行增强(增加额外的方法或添加子资源)。

the standard use case is to enhance the current resource model by additional methods and resources

3.代码实现

3.1 实现ModelProcessor

@Provider
public class MyModelProcessor implements ModelProcessor {
     
    @Override
    public ResourceModel processResourceModel(ResourceModel resourceModel, 
    Configuration configuration) {
     
        //获取类上注册的资源
        List<Resource> resources = resourceModel.getResources();
        for (Resource r : resources) {
     
            //注册路径
            String path = r.getPath();
            //注册的类,至少有一个处理类
            // 注:可以有多个类注册一个路径,但路径下的方法注解不能重复
            Set<Class<?>> handlerClasses = r.getHandlerClasses();
            for (Class clazz : handlerClasses) {
     
                System.out.println(clazz.getName());
            }
            //jersey中路径注册如果为空字符串,则与"/"等效
            if (!path.startsWith("/")) {
     
                path = "/" + path;
            }
            System.out.println("Class resource path: " + path);
            //获取方法上注册的子资源
            List<Resource> childResources = r.getChildResources();
            for (Resource cr : childResources) {
     
                String childPath = cr.getPath();
                if (!childPath.startsWith("/")) {
     
                    childPath = "/" + childPath;
                }
                List<ResourceMethod> methods = cr.getAllMethods();
                for (ResourceMethod m : methods) {
     
                    System.out.println("Child method resource path: " + childPath
                            + " ,method: " + m.getHttpMethod());
                }
            }
            System.out.println("*************************************");
        }
        return resourceModel;
    }

    @Override
    public ResourceModel processSubResource(ResourceModel resourceModel, 
    Configuration configuration) {
     
        return resourceModel;
    }
}

3.2 实现一个用于测试的资源类

@Path("/user")
public class UserRes {
     
    //获取用户列表
    @GET
    @Path("")
    @Produces(MediaType.APPLICATION_JSON)
    public User getAll(@QueryParam("name") String name,
                       @QueryParam("age") @DefaultValue("10") int age) {
     
        User user = new User(name, age);
        return user;
    }
    //创建用户
    @PUT
    @Path("")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    public String add(@FormParam("name") String name,
                      @FormParam("age") int age) {
     
        return "name: " + name + " , age: " + age;
    }
    //删除用户
    @DELETE
    @Path("/{id}")
    public String delete(@PathParam("id") String id) {
     
        return "";
    }
    //修改用户
    @POST
    @Path("/{id}")
    public String update(@PathParam("id") String id) {
     
        return "";
    }
    //获取用户详细信息
    @GET
    @Path("/{id}")
    public String get(@PathParam("id") String id) {
     
        return "";
    }
    //判断用户是否存在
    @HEAD
    @Path("/{id}")
    public String getInfo(@PathParam("id") String id) {
     
        return "";
    }
}

3.3 服务启动

通过封装的CommonServer显示注册MyModelProcessor,启动服务。

public class UserServer {
     
    public static void main(String[] args) throws Exception {
     
        CommonServer server = new CommonServer(8081, "/",
                null,"org.bigdata.filter.MyModelProcessor");
        server.start();
    }
}

关于封装的通用服务器,请参考:Jersey框架:封装基于Jetty的通用服务器

4.效果演示

启动服务,控制台输出的UserRes的资源注册情况如图:
Jersey框架:利用ModelProcessor接口获取所有注册的资源_第1张图片

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

你可能感兴趣的:(Jersey系列:实践全干货,Jersey,Jersey,数据服务,ModelProcessor,资源)