Juliet 是一款轻量级的 Golang 中间件链接助手,将 Context(地图)对象从中间件传递到下一个。
示例:
package main import ( "net/http" "log" "net" "fmt" "github.com/root-gg/juliet" ) // Juliet is a lightweight middleware chaining helper that pass a Context (map) object // from a middleware to the next one. // // Middlewre is a pattern where http request/response are passed through many handlers to reuse code. // For example this classic middleware log the requested url func logMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Our middleware logic goes here... log.Println(r.URL.String()) // Pass the request to the next middleware / handler next.ServeHTTP(w, r) }) } // Juliet adds a context parameter to the middleware pattern that will be passed along the Chain. // For example this middleware puts the request's source IP address in the context. func getSourceIpMiddleware(ctx *juliet.Context, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Get the source IP from the request remote address ip, _, err := net.SplitHostPort(r.RemoteAddr) // You can handle failure at any point of the chain by not calling next.ServeHTTP if err != nil { http.Error(w, "Unable to parse source ip address", 500) return } // Save the source ip in the context ctx.Set("ip", ip) // Pass the request to the next middleware / handler next.ServeHTTP(w, r) }) } // As a context is nothing more that a map[interface{}]interface{} with syntactic sugar you have to ensure you // check types of values you get from the context. To keep your code clean you can write helpers to do that and keep // type safety everywhere. func getSourceIp(ctx *juliet.Context) string { if sourceIP, ok := ctx.Get("ip"); ok { return sourceIP.(string) } return "" } // The last link of a middleware chain is the application Handler func pingHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong\n")) } // Juliet can also pass the context parameter to application Handlers func ipHandler(ctx *juliet.Context, resp http.ResponseWriter, req *http.Request) { // write http response resp.Write([]byte(fmt.Sprintf("your IP address is : %s\n", getSourceIp(ctx)))) } func main(){ // Juliet links middleware and handler with chain objects chain := juliet.NewChain() // Chain objects are immutable and any operation on it returns a new chain object. // You can append one or more middleware to the chain at a time using the Append method. chain = chain.Append(getSourceIpMiddleware) // You can append a middleware to the beginning of the chain with the AppendChain method. // When working with a non context-aware ( Juliet ) middleware you have to use the Adapt method. chain = juliet.NewChain(juliet.Adapt(logMiddleware)).AppendChain(chain) // Now we have this middleware chain : logUrl > getSourceIp > ApplicationHandler // We could have built it in one pass this way : // chain := juliet.NewChain(juliet.Adapt(logMiddleware),getSourceIpMiddleware) // It's now time to add some application handlers and to bind everything to some HTTP route. // With a context handler http.Handle("/ip", chain.Then(ipHandler)) // With a classic http.HandlerFunc http.Handle("/ping", chain.ThenHandlerFunc(pingHandler)) // With a classic http.Handler http.Handle("/404", chain.ThenHandler(http.NotFoundHandler())) log.Fatal(http.ListenAndServe(":1234", nil)) } // $ go run main.go // 2016/02/01 12:20:39 /ip // 2016/02/01 12:20:44 /ping // 2016/02/01 12:20:56 /404 // // $ curl 127.0.0.1:1234/ip // your IP address is : 127.0.0.1 // $ curl 127.0.0.1:1234/ping // pong // $ curl 127.0.0.1:1234/404 // 404 page not found
Problem Description Farmer John has two feuding herds of cattle, the Moontagues and the Cowpulets. One of the bulls in the Moontague herd, Romeo, has fallen in love with Juliet, a Cowpulet. Romeo woul
Description Farmer John has two feuding herds of cattle, the Moontagues and the Cowpulets. One of the bulls in the Moontague herd, Romeo, has fallen in love with Juliet, a Cowpulet. Romeo would like t
作为python 练手的一个小例子 数据来源: 链接:https://pan.baidu.com/s/1u2c7O-617MboXSwBHnoOcA 提取码:vX47 def words_static(file_path): words_static = dict() with open(file_path,"r") as file : for line in
问题 用官网下载的Juliet test,准备make编译下。 发现make后报以下错误: std_thread.o: In function `stdThreadCreate': std_thread.c:(.text+0xae): undefined reference to `pthread_create' std_thread.o: In function `stdThreadJoin':
问题内容: JPanel和JFrame有什么区别,以及与轻量级,重量级的关系? 问题答案: JPanel是允许将多个UI组件放在一起的容器。JFrame是使用Swing编写的窗口。 所有的Swing组件都是所谓的“轻型”组件,因为它们是用Java编写的。例如,如果您运行Swing应用程序并尝试使用UI分析工具(例如Windows中的WinSpy)对其进行分析,则只会看到一个元素:窗口(JFrame
主要内容:使用普通函数创建 goroutine,使用匿名函数创建goroutine在编写 Socket 网络程序时,需要提前准备一个线程池为每一个 Socket 的收发包分配一个线程。开发人员需要在线程数量和 CPU 数量间建立一个对应关系,以保证每个任务能及时地被分配到 CPU 上进行处理,同时避免多个任务频繁地在线程间切换执行而损失效率。 虽然,线程池为逻辑编写者提供了线程分配的抽象机制。但是,如果面对随时随地可能发生的并发和线程处理需求,线程池就不是非常直观和方便了。能否
Jenkins Pipeline插件有一个称为“轻量级签出”的功能,其中主服务器仅从repo中提取Jenkinsfile,而不是整个repo。配置屏幕中有一个相应的复选框。我想在多分支管道中进行轻量级签出,但我在多分支配置屏幕中没有看到复选框。有什么想法如何实现这一点吗?我注意到一些关闭的问题表明此功能可用,但我无法找到任何有关如何实现它的细节。 相关资料: https://issues.jenk
问题内容: 题 我正在寻找Java内存对象缓存API。有什么建议吗?您过去使用过什么解决方案? 当前 现在,我只是在使用地图: 要求 我需要扩展缓存以包括以下基本功能: 最大尺寸 生存时间 但是,我不需要更复杂的功能,例如: 来自多个进程的访问(缓存服务器) 持久性(到磁盘) 意见建议 内存中缓存: Guava CacheBuilder-活动开发。请参阅此演示文稿。 LRUMap-通过API配置。
问题内容: 我目前在一个网站上工作,该网站必须存在于内存可用性非常低的VM上(目前被告知要达到512mb)。不幸的是,至少在不久的将来,数据库和Web应用程序必须是同一台服务器。 现在,我已经在这里通读了一些问题,并尝试进行自己的研究,但是这里有很多选择。从本质上讲,什么是可以安装的轻巧的数据库服务器?SQL或NoSQL并不重要;它不会占用大量数据库资源,但我现在不想随我现在选择的内容而受到限制。
问题内容: 是否有一个提供发布/订阅模式的Java轻量级框架? 一些理想的功能 支持泛型 向发布者注册多个订阅者 API主要是接口和一些有用的实现 完全不需要内存,持久性和事务保证。 我了解JMS,但这对我来说太过分了。发布/订阅的数据是文件系统扫描的结果,扫描结果被馈送到另一个组件进行处理,然后在将其馈给另一个组件之前进行处理,依此类推。 编辑:所有在同一过程中。bean的PropertyCha