撸了个简单的 WebMVC 框架,求吐嘈和 Star/Fork - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Cloudee
V2EX    Java

撸了个简单的 WebMVC 框架,求吐嘈和 Star/Fork

  •  
  •   Cloudee
    cloudeecn 2015-10-23 18:20:23 +08:00 3736 次点击
    这是一个创建于 3723 天前的主题,其中的信息可能已经有所发展或是发生改变。

    陆陆续续用闲暇时间写的自用 MVC 框架,本来想利用十一期间整理整理代码放出来,结果一直拖延症终于缓慢地完工了(然后这帖又写了两天……)

    先放地址: https://github.com/cloudeecn/mocha-mvc 求 Star 和 Fork , orz

    README 和 Wiki 还不全,大家先凑合一下看看这里和 example 工程

    运行环境要求:

    • Java7
    • Servlet3.0 容器

    运行 Example

    clone 工程,用 eclipse/IDEA/whatever 你喜欢的 IDE 导入 maven 工程,用支持 Servlet3.0 的容器启动里面的 example 子工程就 OK 啦

    在 web.xml 中有使用SpringGuice作为 DI 的两套配置,默认打开的是用Guice作 DI 的,也可以打开Spring来试一下。

    Spring的配置在 example 工程中src/main/resources/works/cirno/mocha/example/spring/applicationContext.xml

    Guice的配置在
    works.cirno.mocha.example.guice
    包下

    快速上手

    用过Guice的同学应该对这种方式很熟悉,创建一个works.cirno.mocha.MVCConfigurator的子类,并在public void configure()方法中进行配置。配置好后配置到 DispatcherFilter / DispatcherServlet 的 init-param["configurator"]中

    配置路由项

    serve({路径}[, "GET/POST/PUT..."]) 

    会产生一个路由项,利用方法链的方式可以进一步对匹配这个路径的访问进行配置

    配置响应

    serve({路径}[, "GET/POST/PUT..."]).with({controller}, {method}); 

    中的 with 方法给路由项配置响应的Controller和其中的方法method

    Controller 返回

    Controller 方法可以支持返回一下几个类型

    Integer :直接用 response.sendError 返回返回码

    String :作为 view 的名字寻找对应的 jsp 进行渲染

    View 对象:根据 view 的名字寻找对应的 jsp 进行渲染, view 对象中有 attribute(key, value)方法可以给 request 的 attribute 提供值

    null 或者方法返回类型为 void :不做后续处理

    配置 view 返回

    可以通过 forward 方法执行响应 view 名对应的 jsp 文件( forward 方法返回一个支持 to 方法的接口,其中的 to 方法执行 JSP 的位置)

    可以配置多个

    serve({路径}[, "GET/POST/PUT..."]).with({controller}, {method}) .forward("view 名").to("JSP 位置") .forward("view 名").to("JSP 位置") ... ; 

    支持 Restful 风格的 api

    serve("/parameter/\\+${userId}").with(ParameterController.class, "user").forward("success").to("/WEB-INF/jsp/parameter-rest.jsp"); serve("/parameter/\\+${userId}", "POST").with(ParameterController.class, "userPost"); serve("/parameter/\\+${userId}.json").with(ParameterController.class, "userJson"); 

    会匹配 /parameter/+后面的任何内容,并作为 userId 参数和候选

    目前有两种写法:

    JDK7 终于支持了的 namedGroup :写法如下:(?<name>pattern),会匹配 pattern 正则并且作为 name 参数的候选

    另外支持一种比较基本的${name}写法,会被翻译成(?<name>.*?),最小匹配接下来的内容作为 name 参数的候选

    参数获取

    Controller 方法中的参数目前会根据以下的规则获取:

    1. 按类型匹配

      • 类型为 HttpServletRequest 的参数会给予 request 对象
      • 类型为 HttpServletResponse 的参数会给予 response 对象
      • 类型为 ServletOutputStream 或 OutputStream 的参数会给予 response.getOutputStream()的结果
      • 类型为 PrintWriter 或 Writer 的参数会给予 response.getWriter()的结果
    2. 如果是 multipart 请求,如果参数类型是 InputStream 或者 Reader ,根据参数名匹配上传文件的内容

    3. 根据参数的名称,按照url 中的变量 - multipart 中解析到的表单域 - request.getParameter的顺序获取字符串,并尝试通过系统中的 PropertyEditor 进行类型转换,如果转换成功将转换结果给予参数

    4. 将这个类型用无参构造函数实例化,如果成功作为 JavaBean 遍历其中的属性,根据规则 1-4 获取参数名.属性名的参数值进行填充,如果能获取到至少一个,将这个实例给予参数

    5. 以上都不匹配返回参数的默认值(基本类型给 false/0 ,对象类型给 null )

    TODO

    • 写文档( README.md 居然有只写了一半的句子!)
    • 写文档(注释简直是没有)
    • 写文档( Wiki 也没有!)
    • 修改路径匹配的规则,现在是用正则匹配的,对带正则元字符的的路径不友好
    • 优化获取参数的性能……从 request 中填充一个 5 个属性的 Bean 居然要 16 毫秒简直不能忍
    • 重构一下 View 的结构,现在的 View 机制是在 Renderer 之下的,结构很诡异
    • 用一个比较优雅的方式封装参数获取和转换的配置(目前是写死的规则……)

    随后我会慢慢在 GitHub 的 README.md 和 Wiki 中补充上各种文档,请大家期待;)

    16 条回复    2015-10-28 10:27:23 +08:00
    Comdex
        1
    Comdex  
       2015-10-23 21:46:06 +08:00   1
    撸了个简单的 Java ORM 框架,求吐嘈和 Star/Fork
    https://github.com/Comdex/Cozy
    Cloudee
        2
    Cloudee  
    OP
       2015-10-23 23:42:50 +08:00 via iPhone
    @Comdex 哈哈有没有人撸个简单的 IoC...
    nowcoder
        3
    nowcoder  
       2015-10-24 00:15:58 +08:00   1
    cxshun
        4
    cxshun  
       2015-10-24 00:26:23 +08:00   1
    @Comdex @Cloudee 赞,都已 Star 。
    简单的 IoC ,不错,我也要弄一个。
    unique
        5
    unique  
       2015-10-24 12:37:30 +08:00 via iPhone   1
    Cloudee
        6
    Cloudee  
    OP
       2015-10-24 13:01:23 +08:00
    @unique
    楼上都不错, Star 了 w
    unique
        7
    unique  
       2015-10-24 13:08:43 +08:00 via iPhone
    @Cloudee 1024 快乐!
    Cloudee
        8
    Cloudee  
    OP
       2015-10-24 14:15:42 +08:00
    @unique 同乐 w
    P.S 你那个 blade 的配置语法好现代,感觉我这个还局限在 SpringMVC/Guice Servlet 那个时代的语法上
    unique
        9
    unique  
       2015-10-24 14:51:58 +08:00 via iPhone
    @Cloudee ////)○ 慢慢改进,每一个创造轮子的骚年都有推动技术发展的
    br00k
        10
    br00k  
       2015-10-24 15:35:37 +08:00   1
    Start XD
    wizardforcel
        11
    wizardforcel  
       2015-10-24 17:54:18 +08:00 via Android   1
    。。。有没有人自制了个简单的模板引擎
    Comdex
        12
    Comdex  
       2015-10-25 13:03:15 +08:00
    @unique 路由的闭包用法必须要引入 jdk8 吧?我看简介要求 1.6 都可以?
    unique
        13
    unique  
       2015-10-25 13:59:21 +08:00
    @Comdex 可以的,支持 1.6 以及以上
    Cloudee
        14
    Cloudee  
    OP
       2015-10-25 14:15:42 +08:00 via iPhone
    @Comdex 我的理解是 1.8 可以用闭包, 1.7 以下也可以 new 接口( mocha 的 all 方法也是这样的)
    不知道对不对 @unique
    unique
        15
    unique  
       2015-10-25 14:33:10 +08:00
    @Cloudee yes ,你看看 http://winterbe.com/posts/2014/03/16/java-8-tutorial/ 只要你编写了 1.6 的接口,那么在 1.8 的语法中可以简化,我没有直接使用 jdk1.8 去做,那样看起来更优雅 : )
    moishalo
        16
    moishalo  
       2015-10-28 10:27:23 +08:00   1
    @Cloudee 擦,我来晚了。。。
    瞬间这么多回复了。。。已 Star 。。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2366 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 04:30 PVG 12:30 LAX 20:30 JFK 23:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86