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

2020-06-06 14:04:56 +08:00
 tctc4869

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

比如下面这个: const server = http.createServer((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 框架有这个功能。

5825 次点击
所在节点    Java
64 条回复
tctc4869
2020-06-07 16:37:09 +08:00
jfinal 有么? jfinal 还是得写 Controller 把
hantsy
2020-06-07 16:41:15 +08:00
@751762476 Micronaut 真心不错,功能很全面。如果厌烦了写 Spring,可以试下这个。
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
2020-06-07 20:16:25 +08:00
@hantsy 所谓的性能包袱,实际上就是启动速度慢了,数量众多的自动配置并不影响处理速度。
hantsy
2020-06-07 20:35:59 +08:00
@echo1937
1,启动速度慢会影响到开发效率。
2,运行时,处理请求响应速度也会有一定的影响。用 Spring Boot 启动太多的 Bean,很多你可能根本就用不到,导致一个请求内过多生命周期相关 Bean 参与。
3,再就是运行时资源消耗太多了,这个影响也是比较大,最终影响到项目的运维成本,你可能需要更多的硬件。
taoprogramer
2020-06-09 14:07:24 +08:00
@hantsy
开发效率这个问题你可以用 jrebel 这种工具热加载解决,不需要重启,这些多余的 bean 产生的影响远小于数据库 /中间件读写慢带来的性能问题,绝大部分业务系统只需要在数据读写层面做优化就可以了。
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
2020-06-10 09:29:39 +08:00
写 Vertx Web Router 这种感觉太原始了,和 Spring RouterFunction 体验差了点。
tctc4869
2020-06-10 11:32:37 +08:00
@hantsy 我又不是写太多 Vertx Web Router,我就写几个 Router,然后里面执行自己编写的 Web 处理流程代码去了。
hantsy
2020-06-10 11:45:40 +08:00
哦,上面写错了,近两年-》近两天。
tctc4869
2020-06-11 08:42:07 +08:00
@hantsy 我补充一下吧,想要的是这样一个 webMVC 框架,要做到,接收所有请求,请求分派处理代码( Controller,Action 之类,action 拦截器之类的),请求响应,这一个流程要解耦成三个,接收所有请求,请求分派,响应请求。其中请求分派处理,我自己定义,

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

如果用 servlet,那要造很多轮子。而 vert.x-web 是满足这个条件的,代码非常简单,用很简单的代码就能处理所有请求,还自带了一些编辑的请求与响应方法,比如 fileUploads,接收上传文件。sendFile 下载文件。并不是因为 vert.x 有函数式接口,而是因为他做到了将请求接收,请求分派,响应客户端解耦成三个了。也可以不用框架自带的请求分派,自己编写一条请求分派规则都行。这是我喜欢的一点。
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
2020-06-11 09:16:50 +08:00
@hantsy 那可以直接用 Spring 底层的那个 HTTPHandler 么?如果能用的话,自己如果要方便获取请求与响应,是不是还得写一套代码?
tctc4869
2020-06-11 09:17:57 +08:00
@tctc4869 我的意思不是写 Controller,action,而是响应客户端,获取请求内容的便捷性。
tctc4869
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
2020-06-11 09:41:41 +08:00
@tctc4869 不管是上面我的 Spring MVC Functional,还是 Vertx,还是什么其它都是可以写成这样。只是为了代码维护,按路由规则拆开而已。

你这种 ifelse hole 在正式项目中,只要是个正常人都接受不了这种代码。
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
2020-06-11 09:58:38 +08:00
Micronaut
tctc4869
2020-06-11 10:16:00 +08:00
@xcstream jfinal,找到了,jfinal 的 handler 可以做到
tctc4869
2020-06-11 10:29:48 +08:00
@hantsy 你误解的很厉害了。一个演示代码就让你觉得对方是个只想写 ifelse 的笨蛋

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/679162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX