码迷,mamicode.com
首页 > 编程语言 > 详细

拯救老旧工程,记桥接SpringMVC与Stripes框架

时间:2019-01-03 20:40:13      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:and   思路   逻辑   strip   acea   throws   rip   服务框架   排除   

背景:

  公司基础设施部门推出了自己的微服务框架(以下简称M),要求所有业务应用都要接入进去,但坑爹的是M只提供了SpringMVC工程的support,对于采用Stripes作为MVC框架的应用并不支持,所以就必须重构这个Stripes应用。

  M虽然代替Tomcat自己实现了IO,工作线程池,服务注册发现等等,但还是提供了对Servlet规范的简单支持(移除了web.xml,filter,listener, 打包方式也改成了tar.gz,保留了ServletContext,request,response等等)。

思路与分析:

  由于现有应用的业务逻辑还是比较复杂(沉淀了3,4年),且涉及到多个APP端和其他第三方的交互,所以如果想对应用做完全的重构是一件非常头痛的事情,不仅要投入大量的后端,测试等人力成本,而且整个重构周期也会比较长,影响到对其他需求的响应。

  于是在想:既然SpringMVC和Stripes都遵循Servlet规范,而M又能支持SpringMVC,是否可以通过SpringMVC拦截到所有请求后,把之前的老接口的请求转发给Stripes处理,以后新开发的接口就直接走SpringMVC,这样既兼容了公司的M框架也对原有应用的改动较小,开发周期短,测试人员只需要验证一些系统边界和主要流程,不用再挨个挨个验证已有的业务逻辑,这样可以节省大量人力成本,缩短开发周期。

  SpringMVC是目前最流行的MVC框架,是Spring庞大家族的一员,而Stripes也是一个非常轻量的MVC框架,但是SpringMVC的Controller跟Stripes的ActionBean有个很明显的区别就是前者是单例的,跟状态无关,所有的请求参数都是封装在ServletRequest中的,而后者是prototype,每次请求都会重新生成一个ActionBean对象。

 技术分享图片

动手实现原型:

       新建桥接工程XXX-bridge,所有新增代码均放在新工程,对老工程零侵入,仅新增了pom文件里的两个plugin,可以实现Stripes和SpringMVC两种框架模式下的并行开发,(原来的老工程持续有需求进来)。

    /**
     * 拦截所有请求,如果能映射到Stripes则直接派发给Stripes并return false;
     * 如果不能映射则回退给SpringMVC
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        if (handlerMapping.isEmpty()) {
            return true;
        }
        String url = httpServletRequest.getRequestURI();
        String contextPath = httpServletRequest.getContextPath();
        url = url.replace(contextPath, "").replaceAll("/+", "/");
        LOGGER.info("当前请求路径: {}", url);
        if (!StripesContextHandlerInterceptor.handlerMapping.containsKey(url)) {
            LOGGER.info("请求由SpringMVC处理: {}", url);
            return true;
        }
        try {
            LOGGER.info("请求由Stripes处理: {}", url);
            StripesContextHolder.doService(httpServletRequest.getServletContext(), getApplicationContext(),
                    httpServletRequest, httpServletResponse);
            return false;
        } catch (Exception e) {
            LOGGER.error("处理请求异常:", e);
            return false;
        }
    }

       关键点在于要解析到所有的老接口地址,然后通过拦截器来判断当前请求是否是老接口,是的话就转发给Stripes来处理。其他详细的代码托管在github(已排除掉公司相关信息)

       https://github.com/hiccup234/web-advance/blob/master/bridge.rar

问题与验证:

       1、因为初始化Stripes需要 ServletContext,但是应用启动时却没办法获取到 ServletContext 对象,所以在 StripesContextHolder 里做了懒加载,只有当第一个请求进来后才初始化Stripes。

  2、Stripes是支持queryString为空的查询的,类似:http://127.0.0.1/server/test?list 这种,而M会在解析请求参数的时候对这种情况直接抛异常,经过与基础设施同事协商,他们做出让步,对这种请求的情况直接放行给应用,从而避免了前端和第三方做改造。

 

今晚上线成功,目前跟Tomcat并行发布,5%的流量灰度,观察日志一切正常。前期的技术验证加上近一月的开发测试到今天的上线,算是向着架构的方向迈出了小小一步。

 

未完待续...

拯救老旧工程,记桥接SpringMVC与Stripes框架

标签:and   思路   逻辑   strip   acea   throws   rip   服务框架   排除   

原文地址:https://www.cnblogs.com/ocean234/p/9663255.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!