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

背景:

  公司基础设施部门推出了自己的微服务框架(以下简称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%的流量灰度,观察日志一切正常。前期的技术验证加上近一月的开发测试到今天的上线,算是向着架构的方向迈出了小小一步。

未完待续...

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

时间: 2024-10-10 18:42:52

拯救老旧工程,记桥接SpringMVC与Stripes框架的相关文章

一套老旧ASP+Access的复活记

因公司种种业务需要,需要在机房某台Winserver2008R2服务器的IIS7环境下复活一套ASP+Access的老旧信息化系统,考虑到该服务器本身已有一套ASP+MSSQL的系统线上一直运行正常,想必应该很容易搞定,当即就建了一个二级目录,将全套相关文件拷贝了进去,配置了下相关目录权限后运行之,系统一直在反复而坚定地报同一个错误: 错 误 号:-2147467259错误描述:未指定的错误错误来源:Microsoft JET Database Engine 依次做了如下排查: 该ASP网站AC

老的工程移植到AndroidStudio需要修改的注意事项

之前老的工程用android-apt编译,如果要在新的AndroidStudio编译至少需要修改一下几部分: 1. 修改project里的build.gradle dependencies { classpath "com.android.tools.build:gradle:3.0.0" //一般这一项版本儿较旧,需要修改成像这样高一些的版本儿// classpath 'com.neenbedankt.gradle.plugins:android-apt:1.6'  //这下面两行需

用简单技术对老旧照片进行翻新上色

效果示例: 老旧照片的翻新修改,对于PS新手来说有一定的难度,尤其是网上的教程一般来说都是使用颜色蒙版等较为抽象复杂的技术来进行修改的.经过摸索,我发现其实用PS的”内容识别“填充技术.”色相饱和度“及”色彩平衡“,还有图层的”正片叠底“  等直观常用的简单技术即可解决大部分问题. (首先用扫描仪或是效果较好的数码相机(手机)对老照片进行翻拍和存盘.)  1.“内容识别”填充技术: 从Photoshop CS5版本开始就具备的这个功能让我们能够快速的填充一个选区,用来填充这个选区的像素是通过感知

HomeKit 与老旧设备

苹果推了HomeKit,已经有很多厂商在做,可以达到Siri控制所有设备的功能. 但是Siri也不是万能的,对人类的语义理解也会产生差错,不过我相信未来这个问题会解决掉. 如果家里有老旧的电视机等设备,或者自己做了一个开关窗户的机器,那么Homekit就显得无能为力了. 家里的一些贵重物件比如冰箱,空调等设备也不是说淘汰就淘汰的,当家里充斥着Homtkit设备的时候,其他设备无法受到Homekit的控制,那就很痛苦了. 要做到如此的兼容性,设想如下:   做一个Homekit的Hub,此Hub和

作者没有实战经验,案例老旧,图表水平差:2星|《社群思维》

书中堆砌了一些社群运营的经验技巧,读后感觉作者没没有实际的社群运营经验,经验技巧中没看到有价值的. 案例比较老旧,以小米.黄太吉等知名案例为主,信息和数据好像都是公开可见的资料中整理出来的. 图表做的也比较差,经常是把并列关系的一段文字做成图表. 总体评价2星,不推荐阅读. 全文完 相关链接: 4星|<小群效应>:移动互联网时代,社群的数据与分析 3星|<常青>:强调维护老客户重于争取新客户.有理论缺证明 3星|<伏牛传>:善用移动互联网造势,迎合小众而不是大众口味的餐

用Maven整合SpringMVC+Spring+Hibernate 框架

用Maven整合SpringMVC+Spring+Hibernate 框架, 实现简单的插入数据库数据 一.搭建开始前的准备 1.打开MyEclipse新建Maven项目.File>New>Other(或Ctrl+N)>Maven Project:然后我们用default Workspace就行了(注意Location的路径,区分目录名和项目名):然后再Filter中输入webapp,我们选择org.apache.maven.archetypes 下的maven-archetype-we

记Angular与Django REST框架的一次合作(2):前端组件化——Angular

注:这是这个系列的第二部分,主要集中在Angular的使用方面.之前使用过AngularJS(Angular 1.x),混在Django的模板中使用,这些页面一般完全是结果展示页.在有Django表单输入的页面中,就很难将两者很好的结合起来.自己在学习新版的Angular时,跟了2遍官方网站的“英雄指南”教程.第1次完全是照搬,熟悉了一下基本概念:第2次自己做了一些修改,写了一个图片分享系统(只有一个雏形,还不是特别完善). 推荐IDE:Visual Studio Code 代码: github

用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能(二)

前一篇写的有些多,大家先看前一篇,传送门 具体的资源已将上传到资源了. 附地址:MySQL.zip启动 用Maven整合SpringMVC+Spring+Hibernate 框架 上文我们直接搭建前的准备和资源配置都写好了,下面进入具体代码编写.承接上文的小3 3.我习惯建立接口,这样对整个项目感觉更合理. (1.)建立IBaseService(业务逻辑层,有的习惯写成BaseServiceI)都可以,都是标注接口的,我只是简单的贴下代码 package com.jesus.sshframewo

Spring+SpringMVC+MyBatis+Maven框架整合

本文记录了Spring+SpringMVC+MyBatis+Maven框架整合的记录,主要记录以下几点 一.Maven需要引入的jar包 二.Spring与SpringMVC的配置分离 三.Spring与MyBatis的整合 一.Maven需要引入的jar包 本文默认读者已经掌握Maven的使用,Maven配置片段如下 Xml代码   <!-- 引入spring-webmvc与spring-jdbc --> <dependency> <groupId>org.sprin