跳转至

39 RESTful Web Services(3):明确架构愿景与调用栈顺序

你好,我是徐昊。今天我们继续使用TDD的方式实现RESTful Web Services。

在上节课,我们通过Spike将DI容器引入了实现,代码如下:

static class ResourceServlet extends HttpServlet {
    private final Context context;
    private TestApplication application;
    private Providers providers;
    public ResourceServlet(TestApplication application, Providers providers) {
        this.application = application;
        this.providers = providers;
        context = application.getContext();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Stream<Class<?>> rootResources = application.getClasses().stream().filter(c -> c.isAnnotationPresent(Path.class));

        ResourceContext rc = application.createResourceContext(req, resp);
        Object result = dispatch(req, rootResources, rc);
        MessageBodyWriter<Object> writer = (MessageBodyWriter<Object>) providers.getMessageBodyWriter(result.getClass(), null, null, null);
        writer.writeTo(result, null, null, null, null, null, resp.getOutputStream());
    }

    Object dispatch(HttpServletRequest req, Stream<Class<?>> rootResources, ResourceContext rc) {
        try {
            Class<?> rootClass = rootResources.findFirst().get();
            Object rootResource = rc.initResource(context.get(ComponentRef.of(rootClass)).get());
            Method method = Arrays.stream(rootClass.getMethods()).filter(m -> m.isAnnotationPresent(GET.class)).findFirst().get();
            return method.invoke(rootResource);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

在这个Spike的基础上,我们可以进一步细化架构的愿景:

明确调用栈顺序

接下来需要稍微Spike一下的,就是Resource Dispatcher的部分:

根据Spike的结果,我们可以得到这部分的架构愿景和调用栈顺序:



如上图所示,为大致的组件划分。

  • ResourceServlet:以Servlet的形式作为入口,处理Http请求。
  • Application:指明RESTful应用所需的所有组件,比如Root Resource、Providers等,也是对于框架提供的服务的访问入口。
  • ResourceRouter:Http请求派发算法的实现载体。
  • Providers:三个扩展点,也就是MessageBodyWriter,MessageBodyReader以及ExceptionMapper。

明确了这些之后,就可以进入分解任务的环节了。但是,在这之前,我们要如何处理Spike代码呢?

思考题

在进入下节课之前,希望你能认真思考如下两个问题。

  1. 在当前架构愿景下,我们要如何分解任务?
  2. 关于架构愿景的学习,你有什么收获吗?

欢迎把你的想法分享在留言区,也欢迎把你的项目代码分享出来。相信经过你的思考与实操,学习效果会更好!

精选留言(3)
  • aoe 👍(1) 💬(1)

    留下代码 https://github.com/wyyl1/geektime-tdd-framework/tree/3

    2022-06-16

  • 张铁林 👍(1) 💬(0)

    https://github.com/vfbiby/tdd-restful

    2022-06-18

  • 范飞扬 👍(0) 💬(0)

    好吧,原来dispatcher 变成了ResourceRouter,我说怎么组件元素变少了

    2024-04-29