Java 现在有哪些具备极简处理请求功能的 WebMVC 框架? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tctc4869
V2EX    Java

Java 现在有哪些具备极简处理请求功能的 WebMVC 框架?

  •  
  •   tctc4869 2020-06-06 14:04:56 +08:00 6464 次点击
    这是一个创建于 1960 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前很多 webMVc 框架,基本都要先写 Controller 类,然后注册或写注解,但对于现在的我来说,类似 Spring MVC 那一套衍生的开发体验不太好,不太利于开发者定制(相对于 node.js )。我想更简单地处理请求,直接用一个匿名类或函数式接口来处理所有的请求。因为越简单,就越容易定制。

    比如下面这个: const server = http.crateServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World'); });

    这是 node.js 的官方网址里的某个演示,非常简单的请求处理,就一个函数来处理所有请求

    HttpServer server = Vertx.vertx().createHttpServer(); Router router = Router.router(Vertx.vertx()); router.route().handler(request -> { request.response().end("post");

    }); 还有 java 的 vert.x,不过这个是面向完全响应式开发,对个人和团队的响应式知识掌握,以及代码组织能力都有不小的要求。

    基本有 request 和 response 两个形式参数,其中 response 封装返回视图,返回 body,下载文件,输出图片,设置响应状态码……等常用响应输出的方法。框架本身已经封装了 session 和静态资源处理。

    除了 vert.x,还有哪些 java 框架有这个功能。

    第 1 条附言    2020-06-11 08:48:08 +08:00
    提供一个方法代码接收所有请求,这个代码可以是函数式接口,也可以是一个抽象类或接口里面的抽象方法,该方法会接收所有的入站请求,开发者也可以在这个方法内直接编写响应代码,直接响应给客户端,不用传达给下一个组件处理,也可以调用请求分派器,或调用自己编写的请求分派器,

    本身自带常用的 http 请求内容获取和 http 请求响应方法。例如获取上传文件,跨域处理,输出模板引擎渲染的页面到客户端,输出图片,下载文件,输出字符串等。静态资源过滤

    有人提到了 Servlet,不过用 Servlet 要造很多轮子。
    64 条回复    2020-06-11 11:12:39 +08:00
    2kCS5c0b0ITXE5k2
        1
    2kCS5c0b0ITXE5k2  
       2020-06-06 14:08:31 +08:00
    Spring boot?
    chenuu
        2
    chenuu  
       2020-06-06 14:10:27 +08:00 via Android
    fmumu
        3
    fmumu  
       2020-06-06 14:11:44 +08:00 via Android
    直接基于 servlet 不就行了
    tctc4869
        4
    tctc4869  
    OP
       2020-06-06 14:11:51 +08:00
    @emeab Spring Boot 和我说的不是一个领域的,应该说是 Spring MVC,但是 Spring MVC 我并没有找到匿名类或函数式接口的请求处理的相关代码
    itechify
        5
    itechify  
    PRO
       2020-06-06 14:13:09 +08:00 via Android
    Vert.x
    hantsy
        6
    hantsy  
       2020-06-06 14:14:52 +08:00
    lavvrence
        7
    lavvrence  
       2020-06-06 14:17:07 +08:00
    Kyle18Tang
        8
    Kyle18Tang  
       2020-06-06 14:18:15 +08:00
    @hantsy #6 我也想到了 Webflux
    hantsy
        10
    hantsy  
       2020-06-06 14:45:18 +08:00
    @Kyle18Tang Spring WebMvc 在 Spring 5.2 一样支持 Functional 。

    https://github.com/hantsy/spring-webmvc-functional-sample
    myCupOfTea
        12
    myCupOfTea  
       2020-06-06 15:35:54 +08:00
    Vert.x
    myCupOfTea
        13
    myCupOfTea  
       2020-06-06 15:36:07 +08:00
    你都提到 nodejs 呢 ,那就 Vert.x
    Ariver
        14
    Ariver  
       2020-06-06 15:41:57 +08:00
    play
    可以一试
    hantsy
        15
    hantsy  
       2020-06-06 15:55:25 +08:00
    @Ariver Play 不如 Akka Http 舒服
    yty2012g
        16
    yty2012g  
       2020-06-06 17:21:13 +08:00
    首先,Spring MVC 也是可以只有 request 和 response 参数的,个人觉得并不复杂。其次,按照你的情况,可以推荐你使用 jetty embedded,一个 servlet,参数就是 request 和 response,想怎么定制都行。
    6IbA2bj5ip3tK49j
        17
    6IbA2bj5ip3tK49j  
       2020-06-06 17:23:18 +08:00
    http://sparkjava.com/documentation#getting-started

    个人一些简单的小项目 /工具需要 web 就用这个,完全符合你的要求。
    46Gnj0E0OBmad377
        18
    46Gnj0E0OBmad377  
       2020-06-06 18:30:23 +08:00 via iPhone
    spark 感觉还成,就是楼上发了文档那个
    hantsy
        19
    hantsy  
       2020-06-06 18:41:15 +08:00
    @tsaohai 单纯的 Spark 会让你产生混淆,一般会想到 Apache Spark 。
    hantsy
        20
    hantsy  
       2020-06-06 18:42:02 +08:00
    SparkJava 对 Kotlin 支持不错,想到了 Jetbrains 还有自己的 Ktor 。
    zjsxwc
        21
    zjsxwc  
       2020-06-06 19:55:13 +08:00 via Android
    web 开发用 grails groovy 挺好的
    iyangyuan
        22
    iyangyuan  
       2020-06-07 00:22:52 +08:00 via iPhone
    没看到有人推荐 Nutz,看来我真的老了
    tctc4869
        23
    tctc4869  
    OP
       2020-06-07 00:23:42 +08:00
    @yty2012g
    @hantsy
    我想可能搞错了什么,而且我要的并不是所谓的函数式接口来处理请求,我想要的是一个方法处理所有的请求,与函数式接口相差不大,匿名类就可以弄。在这个方法体内,我自己来处理 request 到 response 的流程。然后借助 MVC 框架本身自带的常用响应方式的代码封装,例如响应 body,响应一个视图以及模板渲染,响应文件下载,响应图片生成等,这些 MVC 框架基本都封装好了。而如果用 Servlet,可能还得重复写轮子。

    我看了一下目前回复里发的 Spring MVC 的那个演示代码,我基本感觉写的很怪异,而且指明 GET,POST,都指明了请求方法,那就处理不了所有的请求了,代码风格好奇怪,感觉明明可以不用那么奇怪的开发风格。可能我没找到关键地方,在此之前,感觉还是回到 Spring MVC 的传统 Controller 来处理比较好。要么就是 vert.x 来做,至少 vert.x-web 写的不是那么难看,而且可以为一个方法配置处理所有的请求,就是很考验响应式编程代码组织能力。
    tctc4869
        24
    tctc4869  
    OP
       2020-06-07 00:30:25 +08:00
    @iyangyuan nutz 能做?目前为止,我在 nutz 文档中,没有找到含有“直接处理所有的请求”的配置方式说明。
    gaius
        25
    gaius  
       2020-06-07 00:32:53 +08:00 via Android
    你这个思路不得反射去调方法
    watzds
        26
    watzds  
       2020-06-07 00:41:32 +08:00 via Android
    处理所有请求有啥好的,那用 filter 吧哈哈
    TMaize
        27
    TMaize  
       2020-06-07 01:01:29 +08:00 via Android
    试试这个,不过不是标准的 servlet
    https://lets-blade.com/
    movistar
        28
    movistar  
       2020-06-07 02:11:30 +08:00
    如果目标只是想接收所有的 HTTP 请求然后统一处理(类似 gateway 做中转,外加一点点简单逻辑这种场景)
    有啥难的啊,现成的 web 框架把对应的 dispatcher 删了重写一个就完事了....
    什么 HTTP 框架都好改,又不是不能改框架的源代码....

    当然最好的方式当然是用 lua 写在 nginx 上,不过如果只熟悉 Java 技术栈,性能要求也不高的情况下,那都可以
    roundgis
        29
    roundgis  
       2020-06-07 03:14:12 +08:00 via Android   1
    javalin
    46Gnj0E0OBmad377
        30
    46Gnj0E0OBmad377  
       2020-06-07 04:07:43 +08:00
    @hantsy #19 我也发现了这个问题,一直不知道怎么称呼这个东西 是不是就叫 sparkjava 。。。
    cgpiao
        31
    cgpiao  
       2020-06-07 07:23:22 +08:00 via Android
    Http4k
    kidcats
        32
    kidcats  
       2020-06-07 08:13:18 +08:00 via Android
    ktor 貌似也不错
    hantsy
        33
    hantsy  
       2020-06-07 09:04:52 +08:00
    @tctc4869 你可能 Java 8 的语法不熟悉吧。只是把处理的部分抽出来了而已。实际应用所有的代码放到一个方法,不现实。

    Spring WebMvc 和 WebFlux 的 API 基本是一致的(当然是不同的实现),除了 MVC 不用 Reactor ( Mono, Flux ),而用传统的 Imperative APIs 外。
    hantsy
        34
    hantsy  
       2020-06-07 09:07:47 +08:00
    @tctc4869 NodeJS Express 我也写,从来没把所有的逻辑放到一个方法里面,routes 也层层传递下去。放到一个方法(或者 Fun )里面只是做 Demo 的时候才用的。
    hantsy
        35
    hantsy  
       2020-06-07 09:11:03 +08:00
    @cgpiao 这个货有一个系列,http 4X, 不过不怎么流行。

    Spring 真正做到编程 Functional 化,我们期待 Spring Fu 吧,目前 0.3,我刚开始玩。

    https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/kofu-reactive-mongo/src/main/kotlin/com/example/demo/DemoApplication.kt
    realkenshinji
        36
    realkenshinji  
       2020-06-07 09:47:26 +08:00 via iPhone
    sparkjava ?
    tt0411
        37
    tt0411  
       2020-06-07 12:36:18 +08:00
    sparkjava, 写简单的服务够用; 但是当服务复杂性上去后, 还是逐渐走向 spring boot
    fanfpy
        38
    fanfpy  
       2020-06-07 13:09:11 +08:00
    blade?
    xcstream
        39
    xcstream  
       2020-06-07 16:03:09 +08:00
    jfinal
    751762476
        40
    751762476  
       2020-06-07 16:34:32 +08:00
    jooby
    Micronaut
    vertx
    ktor
    tctc4869
        41
    tctc4869  
    OP
       2020-06-07 16:37:09 +08:00
    jfinal 有么? jfinal 还是得写 Controller 把
    hantsy
        42
    hantsy  
       2020-06-07 16:41:15 +08:00
    @751762476 Micronaut 真心不错,功能很全面。如果厌烦了写 Spring,可以试下这个。
    hantsy
        43
    hantsy  
       2020-06-07 19:22:06 +08:00
    @tt0411 这个跟工具框架本身没有什么关系,关键生态不一样。Spring 的生态太成熟,使用它是为了偷懒。

    其实项目到了一定程度,你会发现 Spring Boot 默认自动配置会成为很大一个性能包袱,加载的东西太多了。

    我的最简单的例子,同样的 CRUD 功能(使用数据库)在 Quarkus 下启动快很多,如果用 Native Image 打包,最终启动会比 Spring Boot 快 20 倍以上。

    https://github.com/hantsy/quarkus-sample/blob/master/docs/01-start.md 使用 Native Image 打包在 Docker 中启动仅 0.267 秒。

    有些具有极客文化的小公司很抵制 Spring Boot 傻瓜式的自动配置,而坚持用一些简洁的框架(全部手动配置)。
    echo1937
        44
    echo1937  
       2020-06-07 20:16:25 +08:00
    @hantsy 所谓的性能包袱,实际上就是启动速度慢了,数量众多的自动配置并不影响处理速度。
    hantsy
        45
    hantsy  
       2020-06-07 20:35:59 +08:00
    @echo1937
    1,启动速度慢会影响到开发效率。
    2,运行时,处理请求响应速度也会有一定的影响。用 Spring Boot 启动太多的 Bean,很多你可能根本就用不到,导致一个请求内过多生命周期相关 Bean 参与。
    3,再就是运行时资源消耗太多了,这个影响也是比较大,最终影响到项目的运维成本,你可能需要更多的硬件。
    taoprogramer
        46
    taoprogramer  
       2020-06-09 14:07:24 +08:00
    @hantsy
    开发效率这个问题你可以用 jrebel 这种工具热加载解决,不需要重启,这些多余的 bean 产生的影响远小于数据库 /中间件读写慢带来的性能问题,绝大部分业务系统只需要在数据读写层面做优化就可以了。
    hantsy
        47
    hantsy  
       2020-06-10 09:23:12 +08:00
    好了,看到有不少用在用 Vertx 。近两年玩了一下 Vertx+Quarkus+Munity,有一个问题请教,https://stackoverflow.com/questions/62275644/failure-handler-issue-using-vertx-web-routes-and-minity-in-a-quarkus-application
    hantsy
        48
    hantsy  
       2020-06-10 09:29:39 +08:00
    写 Vertx Web Router 这种感觉太原始了,和 Spring RouterFunction 体验差了点。
    tctc4869
        49
    tctc4869  
    OP
       2020-06-10 11:32:37 +08:00
    @hantsy 我又不是写太多 Vertx Web Router,我就写几个 Router,然后里面执行自己编写的 Web 处理流程代码去了。
    hantsy
        50
    hantsy  
       2020-06-10 11:45:40 +08:00
    哦,上面写错了,近两年-》近两天。
    tctc4869
        51
    tctc4869  
    OP
       2020-06-11 08:42:07 +08:00
    @hantsy 我补充一下吧,想要的是这样一个 webMVC 框架,要做到,接收所有请求,请求分派处理代码( Controller,Action 之类,action 拦截器之类的),请求响应,这一个流程要解耦成三个,接收所有请求,请求分派,响应请求。其中请求分派处理,我自己定义,

    响应客户端和获取请求内容,框架本身自带常用请求获取和响应方法,开发者只需调用就可以,例如获取上传文件,跨域处理,下载文件,输出字符串,输出模板引擎渲染的动态页面。输出生成的图片到客户端。也容易扩展

    如果用 servlet,那要造很多轮子。而 vert.x-web 是满足这个条件的,代码非常简单,用很简单的代码就能处理所有请求,还自带了一些编辑的请求与响应方法,比如 fileUploads,接收上传文件。sendFile 下载文件。并不是因为 vert.x 有函数式接口,而是因为他做到了将请求接收,请求分派,响应客户端解耦成三个了。也可以不用框架自带的请求分派,自己编写一条请求分派规则都行。这是我喜欢的一点。
    hantsy
        52
    hantsy  
       2020-06-11 09:05:10 +08:00
    @tctc4869 没看出来那么大差别。
    Spring 的 Controller,RouterFunction 最终都是 Spring 底层的 HTTPHandler 处理的。他们差别只是在于 Path 匹配方式,Path 相应的 Handler 写法不一样而已。两种方式几乎可以 100%互换。对于开发人员只是看你喜欢哪种方式而已。

    在 Quarkus 中,它扩展原来的 Vertx Web Router,支持 Annotation 方式。https://quarkus.io/guides/reactive-routes
    tctc4869
        53
    tctc4869  
    OP
       2020-06-11 09:16:50 +08:00
    @hantsy 那可以直接用 Spring 底层的那个 HTTPHandler 么?如果能用的话,自己如果要方便获取请求与响应,是不是还得写一套代码?
    tctc4869
        54
    tctc4869  
    OP
       2020-06-11 09:17:57 +08:00
    @tctc4869 我的意思不是写 Controller,action,而是响应客户端,获取请求内容的便捷性。
    tctc4869
        55
    tctc4869  
    OP
       2020-06-11 09:35:58 +08:00
    @hantsy
    能直接做到类似下面的代码么?
    演示代码:
    public void handler(request,response){

    if(request.path=="/test/test2"&& request.mothed=="Post"){
    response.endError(403)
    }else if(request.path=="/test/test3"){
    response.end("hello word");
    }else if(request.path=="/test/test4"){
    response.set("abc","123");
    response.View("/test/test4.html");
    }else if(request.path=="/test/test5"){
    Set<File> files= request.getFiles();
    }else if(request.path=="/test/test6"){
    response.endFile(new File("d:/1.txt"))
    }else{
    response.sendRedirect("www.baidu.com");
    }

    }
    hantsy
        56
    hantsy  
       2020-06-11 09:41:41 +08:00
    @tctc4869 不管是上面我的 Spring MVC Functional,还是 Vertx,还是什么其它都是可以写成这样。只是为了代码维护,按路由规则拆开而已。

    你这种 ifelse hole 在正式项目中,只要是个正常人都接受不了这种代码。
    hantsy
        57
    hantsy  
       2020-06-11 09:47:30 +08:00
    你可以直接用原始 Servlet 就好了,满足你的全部要求。

    https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html

    override `service` 方法就行了,其它 doXXX 直接调用 service 。
    putaozhenhaochi
        58
    putaozhenhaochi  
       2020-06-11 09:58:38 +08:00
    Micronaut
    tctc4869
        59
    tctc4869  
    OP
       2020-06-11 10:16:00 +08:00
    @xcstream jfinal,找到了,jfinal 的 handler 可以做到
    tctc4869
        60
    tctc4869  
    OP
       2020-06-11 10:29:48 +08:00
    @hantsy 你误解的很厉害了。一个演示代码就让你觉得对方是个只想写 ifelse 的笨蛋
    hantsy
        61
    hantsy  
       2020-06-11 10:35:34 +08:00
    写一个 Servlet,比如叫 MyServlet,映射到所有的 Request,/*
    剩下的就是一个方法接收两个参数 request, response,想怎么搞都行。

    没遇到 Apache Struts 1 之前,很多人都是这么写的。恶梦一般的回忆。那是 15 年前的事了。
    tctc4869
        62
    tctc4869  
    OP
       2020-06-11 10:59:29 +08:00
    @hantsy 我的目的是拦截所有请求,调用自己的路由规则处理请求,同时需要便捷的请求内容获取和响应客户端的工具类。

    正因为 servlet 太原始了,我才不想用 servlet,servlet 获取请求内容和设置响应的代码有点嗦,如果要编写响应ajax,文件下载,文件上传,渲染动态页面(不是 jsp,是 html ),就得写重复的工具轮子。

    国内有一个叫 jfinal 的框架做到了,它有一个 handler 组件,组成非常简单,能拦截任何请求,可以在当前直接处理请求响应客户端,也可以下一步用框架自带的路由规则处理,也可以调用开发者自己定义的路由规则处理。而且还封装了 request,response 工具类。非常方便。
    hantsy
        63
    hantsy  
       2020-06-11 11:11:17 +08:00
    @tctc4869 Spring Reactive 中 https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/server/HandlerFunction.html
    还上面提到的 Spring WebMvc Functional 版本与这个类似,只是不用 Reactor 。我上面帖出的代码,都是用 Method Reference (如果用 Labmda 也一样),你找不到这个接口痕迹而已。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2612 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 12:31 PVG 20:31 LAX 05:31 JFK 08:31
    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