目前很多 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 框架有这个功能。
1
2kCS5c0b0ITXE5k2 2020-06-06 14:08:31 +08:00
Spring boot?
|
2
chenuu 2020-06-06 14:10:27 +08:00 via Android
|
3
fmumu 2020-06-06 14:11:44 +08:00 via Android
直接基于 servlet 不就行了
|
4
tctc4869 OP @emeab Spring Boot 和我说的不是一个领域的,应该说是 Spring MVC,但是 Spring MVC 我并没有找到匿名类或函数式接口的请求处理的相关代码
|
5
oneisall8955 2020-06-06 14:13:09 +08:00 via Android
Vert.x
|
6
hantsy 2020-06-06 14:14:52 +08:00
@tctc4869 Spring 5 最大的特点就是 Functional 编程模式。
https://github.com/hantsy/spring-reactive-sample/blob/master/boot-start-routes/src/main/java/com/example/demo/DemoApplication.java |
7
jaylee4869 2020-06-06 14:17:07 +08:00
使用 Spring WebFlux 试试: https://spring.io/guides/gs/reactive-rest-service/
|
8
Kyle18Tang 2020-06-06 14:18:15 +08:00
@hantsy #6 我也想到了 Webflux
|
9
hantsy 2020-06-06 14:18:52 +08:00
|
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 |
11
hantsy 2020-06-06 14:52:40 +08:00
|
12
myCupOfTea 2020-06-06 15:35:54 +08:00
Vert.x
|
13
myCupOfTea 2020-06-06 15:36:07 +08:00
你都提到 nodejs 呢 ,那就 Vert.x
|
14
Ariver 2020-06-06 15:41:57 +08:00
play
可以一试 |
16
yty2012g 2020-06-06 17:21:13 +08:00
首先,Spring MVC 也是可以只有 request 和 response 参数的,个人觉得并不复杂。其次,按照你的情况,可以推荐你使用 jetty embedded,一个 servlet,参数就是 request 和 response,想怎么定制都行。
|
17
6IbA2bj5ip3tK49j 2020-06-06 17:23:18 +08:00
|
18
tsaohai 2020-06-06 18:30:23 +08:00 via iPhone
spark 感觉还成,就是楼上发了文档那个
|
20
hantsy 2020-06-06 18:42:02 +08:00
SparkJava 对 Kotlin 支持不错,想到了 Jetbrains 还有自己的 Ktor 。
|
21
zjsxwc 2020-06-06 19:55:13 +08:00 via Android
web 开发用 grails groovy 挺好的
|
22
iyangyuan 2020-06-07 00:22:52 +08:00 via iPhone
没看到有人推荐 Nutz,看来我真的老了😂
|
23
tctc4869 OP @yty2012g
@hantsy 我想可能搞错了什么,而且我要的并不是所谓的函数式接口来处理请求,我想要的是一个方法处理所有的请求,与函数式接口相差不大,匿名类就可以弄。在这个方法体内,我自己来处理 request 到 response 的流程。然后借助 MVC 框架本身自带的常用响应方式的代码封装,例如响应 body,响应一个视图以及模板渲染,响应文件下载,响应图片生成等,这些 MVC 框架基本都封装好了。而如果用 Servlet,可能还得重复写轮子。 我看了一下目前回复里发的 Spring MVC 的那个演示代码,我基本感觉写的很怪异,而且指明 GET,POST,都指明了请求方法,那就处理不了所有的请求了,代码风格好奇怪,感觉明明可以不用那么奇怪的开发风格。可能我没找到关键地方,在此之前,感觉还是回到 Spring MVC 的传统 Controller 来处理比较好。要么就是 vert.x 来做,至少 vert.x-web 写的不是那么难看,而且可以为一个方法配置处理所有的请求,就是很考验响应式编程代码组织能力。 |
24
tctc4869 OP @iyangyuan nutz 能做?目前为止,我在 nutz 文档中,没有找到含有“直接处理所有的请求”的配置方式说明。
|
25
gaius 2020-06-07 00:32:53 +08:00 via Android
你这个思路不得反射去调方法🐶
|
26
watzds 2020-06-07 00:41:32 +08:00 via Android
处理所有请求有啥好的,那用 filter 吧哈哈
|
27
TMaize 2020-06-07 01:01:29 +08:00 via Android
试试这个,不过不是标准的 servlet
https://lets-blade.com/ |
28
movistar 2020-06-07 02:11:30 +08:00
如果目标只是想接收所有的 HTTP 请求然后统一处理(类似 gateway 做中转,外加一点点简单逻辑这种场景)
有啥难的啊,现成的 web 框架把对应的 dispatcher 删了重写一个就完事了.... 什么 HTTP 框架都好改,又不是不能改框架的源代码.... 当然最好的方式当然是用 lua 写在 nginx 上,不过如果只熟悉 Java 技术栈,性能要求也不高的情况下,那都可以 |
29
roundgis 2020-06-07 03:14:12 +08:00 via Android 1
javalin
|
31
cgpiao 2020-06-07 07:23:22 +08:00 via Android
Http4k
|
32
kidcats 2020-06-07 08:13:18 +08:00 via Android
ktor 貌似也不错
|
33
hantsy 2020-06-07 09:04:52 +08:00
@tctc4869 你可能 Java 8 的语法不熟悉吧。只是把处理的部分抽出来了而已。实际应用所有的代码放到一个方法,不现实。
Spring WebMvc 和 WebFlux 的 API 基本是一致的(当然是不同的实现),除了 MVC 不用 Reactor ( Mono, Flux ),而用传统的 Imperative APIs 外。 |
34
hantsy 2020-06-07 09:07:47 +08:00
@tctc4869 NodeJS Express 我也写,从来没把所有的逻辑放到一个方法里面,routes 也层层传递下去。放到一个方法(或者 Fun )里面只是做 Demo 的时候才用的。
|
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 |
36
realkenshinji 2020-06-07 09:47:26 +08:00 via iPhone
sparkjava ?
|
37
tt0411 2020-06-07 12:36:18 +08:00
sparkjava, 写简单的服务够用; 但是当服务复杂性上去后, 还是逐渐走向 spring boot
|
38
fanfpy 2020-06-07 13:09:11 +08:00
blade?
|
39
xcstream 2020-06-07 16:03:09 +08:00
jfinal
|
40
751762476 2020-06-07 16:34:32 +08:00
jooby
Micronaut vertx ktor |
41
tctc4869 OP jfinal 有么? jfinal 还是得写 Controller 把
|
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 傻瓜式的自动配置,而坚持用一些简洁的框架(全部手动配置)。 |
45
hantsy 2020-06-07 20:35:59 +08:00
@echo1937
1,启动速度慢会影响到开发效率。 2,运行时,处理请求响应速度也会有一定的影响。用 Spring Boot 启动太多的 Bean,很多你可能根本就用不到,导致一个请求内过多生命周期相关 Bean 参与。 3,再就是运行时资源消耗太多了,这个影响也是比较大,最终影响到项目的运维成本,你可能需要更多的硬件。 |
46
taoprogramer 2020-06-09 14:07:24 +08:00
@hantsy
开发效率这个问题你可以用 jrebel 这种工具热加载解决,不需要重启,这些多余的 bean 产生的影响远小于数据库 /中间件读写慢带来的性能问题,绝大部分业务系统只需要在数据读写层面做优化就可以了。 |
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
|
48
hantsy 2020-06-10 09:29:39 +08:00
写 Vertx Web Router 这种感觉太原始了,和 Spring RouterFunction 体验差了点。
|
49
tctc4869 OP @hantsy 我又不是写太多 Vertx Web Router,我就写几个 Router,然后里面执行自己编写的 Web 处理流程代码去了。
|
50
hantsy 2020-06-10 11:45:40 +08:00
哦,上面写错了,近两年-》近两天。
|
51
tctc4869 OP @hantsy 我补充一下吧,想要的是这样一个 webMVC 框架,要做到,接收所有请求,请求分派处理代码( Controller,Action 之类,action 拦截器之类的),请求响应,这一个流程要解耦成三个,接收所有请求,请求分派,响应请求。其中请求分派处理,我自己定义,
而 响应客户端和获取请求内容,框架本身自带常用请求获取和响应方法,开发者只需调用就可以,例如获取上传文件,跨域处理,下载文件,输出字符串,输出模板引擎渲染的动态页面。输出生成的图片到客户端。也容易扩展 如果用 servlet,那要造很多轮子。而 vert.x-web 是满足这个条件的,代码非常简单,用很简单的代码就能处理所有请求,还自带了一些编辑的请求与响应方法,比如 fileUploads,接收上传文件。sendFile 下载文件。并不是因为 vert.x 有函数式接口,而是因为他做到了将请求接收,请求分派,响应客户端解耦成三个了。也可以不用框架自带的请求分派,自己编写一条请求分派规则都行。这是我喜欢的一点。 |
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 |
53
tctc4869 OP @hantsy 那可以直接用 Spring 底层的那个 HTTPHandler 么?如果能用的话,自己如果要方便获取请求与响应,是不是还得写一套代码?
|
55
tctc4869 OP @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"); } } |
56
hantsy 2020-06-11 09:41:41 +08:00
@tctc4869 不管是上面我的 Spring MVC Functional,还是 Vertx,还是什么其它都是可以写成这样。只是为了代码维护,按路由规则拆开而已。
你这种 ifelse hole 在正式项目中,只要是个正常人都接受不了这种代码。 |
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 。 |
58
putaozhenhaochi 2020-06-11 09:58:38 +08:00
Micronaut
|
61
hantsy 2020-06-11 10:35:34 +08:00
写一个 Servlet,比如叫 MyServlet,映射到所有的 Request,/*
剩下的就是一个方法接收两个参数 request, response,想怎么搞都行。 没遇到 Apache Struts 1 之前,很多人都是这么写的。恶梦一般的回忆。那是 15 年前的事了。 |
62
tctc4869 OP @hantsy 我的目的是拦截所有请求,调用自己的路由规则处理请求,同时需要便捷的请求内容获取和响应客户端的工具类。
正因为 servlet 太原始了,我才不想用 servlet,servlet 获取请求内容和设置响应的代码有点啰嗦,如果要编写响应 ajax,文件下载,文件上传,渲染动态页面(不是 jsp,是 html ),就得写重复的工具轮子。 国内有一个叫 jfinal 的框架做到了,它有一个 handler 组件,组成非常简单,能拦截任何请求,可以在当前直接处理请求响应客户端,也可以下一步用框架自带的路由规则处理,也可以调用开发者自己定义的路由规则处理。而且还封装了 request,response 工具类。非常方便。 |
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 也一样),你找不到这个接口痕迹而已。 |
64
hantsy 2020-06-11 11:12:39 +08:00
|