ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java扩展Nginx之六:两大filter [打印本页]

作者: 我可以不吃啊    时间: 2023-7-16 09:25
标题: Java扩展Nginx之六:两大filter
欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览

Nginx Header Filter


  1. location /headerfilterdemo {
  2.         content_handler_type 'java';
  3.     content_handler_name 'com.bolingcavalry.simplehello.HelloHandler';
  4.     # header filter的类型是java
  5.     header_filter_type 'java';
  6.     # header
  7.     header_filter_name 'com.bolingcavalry.filterdemo.RemoveAndAddMoreHeaders';
  8. }
复制代码
  1. package com.bolingcavalry.filterdemo;
  2. import nginx.clojure.java.Constants;
  3. import nginx.clojure.java.NginxJavaHeaderFilter;
  4. import java.util.Map;
  5. public class RemoveAndAddMoreHeaders implements NginxJavaHeaderFilter {
  6.     @Override
  7.     public Object[] doFilter(int status, Map<String, Object> request, Map<String, Object> responseHeaders) {
  8.         // 先删再加,相当于修改了Content-Type的值
  9.         responseHeaders.remove("Content-Type");
  10.         responseHeaders.put("Content-Type", "text/html");
  11.         // 增加两个header
  12.         responseHeaders.put("Xfeep-Header", "Hello2!");
  13.         responseHeaders.put("Server", "My-Test-Server");
  14.         // 返回PHASE_DONE表示告知nginx-clojure框架,当前filter正常,可以继续执行其他的filter和handler
  15.         return Constants.PHASE_DONE;
  16.     }
  17. }
复制代码
Nginx Body Filter的第一个场景:字符串body(string faced Java body filter)


  1. # body filter的demo,response body是字符串类型
  2. location /stringbodyfilterdemo {
  3.         content_handler_type 'java';
  4.         content_handler_name 'com.bolingcavalry.simplehello.HelloHandler';
  5.         # body filter的类型是java
  6.         body_filter_type 'java';
  7.     # body filter的类
  8.     body_filter_name 'com.bolingcavalry.filterdemo.StringFacedUppercaseBodyFilter';
  9. }
复制代码
  1. package com.bolingcavalry.filterdemo;
  2. import nginx.clojure.java.StringFacedJavaBodyFilter;
  3. import java.io.IOException;
  4. import java.util.Map;
  5. public class StringFacedUppercaseBodyFilter extends StringFacedJavaBodyFilter {
  6.     @Override
  7.     protected Object[] doFilter(Map<String, Object> request, String body, boolean isLast) throws IOException {
  8.         if (isLast) {
  9.             // isLast等于true,表示当前web请求过程中最后一次调用doFilter方法,
  10.             // body是完整response body的最后一部分,
  11.             // 此时返回的status应该不为空,这样nginx-clojure框架就会完成body filter的执行流程,将status和聚合后的body返回给客户端
  12.             return new Object[] {200, null, body.toUpperCase()};
  13.         }else {
  14.             // isLast等于false,表示当前web请求过程中,doFilter方法还会被继续调用,当前调用只是多次中的一次而已,
  15.             // body是完整response body的其中一部分,
  16.             // 此时返回的status应该为空,这样nginx-clojure框架就继续body filter的执行流程,继续调用doFilter
  17.             return new Object[] {null, null, body.toUpperCase()};
  18.         }
  19.     }
  20. }
复制代码
Nginx Body Filter的第二个场景:二进制流body(stream faced Java body filter)


  1. location /largebody {
  2.         content_handler_type 'clojure';
  3.     content_handler_code '
  4.             (do
  5.                 (use \'[nginx.clojure.core])
  6.             (fn[req]
  7.                     {:status 200
  8.                  :headers {}
  9.                  :body (for [i (range 1024)] "123456789\n")})
  10.         )';
  11. }
复制代码
  1. package com.bolingcavalry.filterdemo;
  2. import nginx.clojure.NginxChainWrappedInputStream;
  3. import nginx.clojure.NginxClojureRT;
  4. import nginx.clojure.java.NginxJavaBodyFilter;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.Map;
  8. public class StreamFacedBodyFilter implements NginxJavaBodyFilter {
  9.     @Override
  10.     public Object[] doFilter(Map<String, Object> request, InputStream bodyChunk, boolean isLast) throws IOException {
  11.         // 这里仅将二进制文件长度打印到日志,您可以按照业务实际情况自行修改
  12.         NginxClojureRT.log.info("isLast [%s], total [%s]", String.valueOf(isLast), String.valueOf(bodyChunk.available()));
  13.         // NginxChainWrappedInputStream的成员变量index记录的读取的位置,本次用完后要重置位置,因为doFilter之外的代码中可能也会读取bodyChunk
  14.         ((NginxChainWrappedInputStream)bodyChunk).rewind();
  15.         if (isLast) {
  16.             // isLast等于true,表示当前web请求过程中最后一次调用doFilter方法,
  17.             // body是完整response body的最后一部分,
  18.             // 此时返回的status应该不为空,这样nginx-clojure框架就会完成body filter的执行流程,将status和聚合后的body返回给客户端
  19.             return new Object[] {200, null, bodyChunk};
  20.         }else {
  21.             // isLast等于false,表示当前web请求过程中,doFilter方法还会被继续调用,当前调用只是多次中的一次而已,
  22.             // body是完整response body的其中一部分,
  23.             // 此时返回的status应该为空,这样nginx-clojure框架就继续body filter的执行流程,继续调用doFilter
  24.             return new Object[] {null, null, bodyChunk};
  25.         }
  26.     }
  27. }
复制代码
  1.         location /streambodyfilterdemo {
  2.             # body filter的类型是java
  3.             body_filter_type java;
  4.             body_filter_name 'com.bolingcavalry.filterdemo.StreamFacedBodyFilter';
  5.             proxy_http_version 1.1;
  6.             proxy_buffering off;
  7.             proxy_pass http://localhost:8080/largebody;
  8.         }
复制代码
  1. 2022-02-15 21:34:38[info][23765][main]isLast [false], total [3929]
  2. 2022-02-15 21:34:38[info][23765][main]isLast [false], total [4096]
  3. 2022-02-15 21:34:38[info][23765][main]isLast [false], total [2215]
  4. 2022-02-15 21:34:38[info][23765][main]isLast [true], total [0]
复制代码
源码下载

名称链接备注项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4