Undertow 作为一个web服务器,是支持反向代理的,比较适用小型平台或者开发测试场景, 以下是使用记录

首先在pom中引用undertow作为web服务器,我使用的springboot项目,配置参考

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency><!--  <dependency><groupId>org.mitre.dsmiley.httpproxy</groupId><artifactId>smiley-http-proxy-servlet</artifactId><version>1.11</version></dependency>--></dependencies>

注: 上面注释的部分,是因为开始用httpclient 做代理,使用也比较简单,有兴趣可以百度一下,后来猜想undertow应该具有反向代理的功能,再引入smilley就有些多余了

undertow 默认的反向代理只能代理整个服务,不能类似nginx 代理某个具体路径,而恰巧我需要该项目能够将 /base路径开始的请求代理转发到其他服务,故而这里取了个巧,先看代码

package com.iflytek.research.datawood.config;import java.net.URI;import javax.annotation.Resource;import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.DisallowedMethodsHandler;
import io.undertow.server.handlers.proxy.ProxyClient;
import io.undertow.server.handlers.proxy.ProxyHandler;
import io.undertow.server.handlers.proxy.SimpleProxyClientProvider;
import io.undertow.util.HttpString;/*** @author ljgeng**/
@Configuration
public class UndertowConfiguration {@Resourceprivate ProxyProperties ProxyProperties;@Beanpublic WebServerFactoryCustomizer<UndertowServletWebServerFactory> custom(){return new WebServerFactoryCustomizer<UndertowServletWebServerFactory>() {@Overridepublic void customize(UndertowServletWebServerFactory factory) {factory.addDeploymentInfoCustomizers(deploymentInfo -> {deploymentInfo.addInitialHandlerChainWrapper(new GatewayProxyHandlerWrapper());});}}; } /*** Gateway  反向代理*  http://undertow.io/undertow-docs/undertow-docs-2.0.0/index.html#reverse-proxy* @author ljgeng**/public class GatewayProxyHandlerWrapper implements HandlerWrapper {@Overridepublic HttpHandler wrap(HttpHandler handler) {// 代理路径ProxyClient proxyClientProvider = new ProxyClientProvider(URI.create(ProxyProperties.getGateway().getUrl()));HttpString[] disallowedHttpMethods = { HttpString.tryFromString("TRACE"),HttpString.tryFromString("TRACK") };return new ProxyHandler(proxyClientProvider, 0,  new DisallowedMethodsHandler(handler, disallowedHttpMethods));}}public class ProxyClientProvider extends SimpleProxyClientProvider {public ProxyClientProvider(URI uri) {super(uri);}/***  重写findTarget 方法: 指定转发的路径。*/@Overridepublic ProxyTarget findTarget(HttpServerExchange exchange) {// 代理/base路径if (exchange.getRequestPath().startsWith("/base")) {// 修改路径,去除baseexchange.setResolvedPath("/base");return super.findTarget(exchange);}return null;}}}

主要看ProxyClientProvider,它重新实现了SimpleProxyClientProvider findTarget方法,当请求路径以/base开始时调用父类方法,否则返回null. 方法exchange.setResolvedPath("/base") 是让代理的路径不再包含base。 可能有人会好奇,为什么这里返回null就可以绕过代理,弄清这个问题的话就要看下ProxyHandler的handleRequest方法到底做了什么(undertow通过handler的handleRequest对请求进行下一步处理)

public void handleRequest(final HttpServerExchange exchange) throws Exception {final ProxyClient.ProxyTarget target = proxyClient.findTarget(exchange);if (target == null) {log.debugf("No proxy target for request to %s", exchange.getRequestURL());next.handleRequest(exchange);return;}if(exchange.isResponseStarted()) {//we can't proxy a request that has already started, this is basically a server configuration errorUndertowLogger.REQUEST_LOGGER.cannotProxyStartedRequest(exchange);exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);exchange.endExchange();return;}final long timeout = maxRequestTime > 0 ? System.currentTimeMillis() + maxRequestTime : 0;int maxRetries = maxConnectionRetries;if(target instanceof ProxyClient.MaxRetriesProxyTarget) {maxRetries = Math.max(maxRetries, ((ProxyClient.MaxRetriesProxyTarget) target).getMaxRetries());}final ProxyClientHandler clientHandler = new ProxyClientHandler(exchange, target, timeout, maxRetries, idempotentRequestPredicate);if (timeout > 0) {final XnioExecutor.Key key = WorkerUtils.executeAfter(exchange.getIoThread(), new Runnable() {@Overridepublic void run() {clientHandler.cancel(exchange);}}, maxRequestTime, TimeUnit.MILLISECONDS);exchange.putAttachment(TIMEOUT_KEY, key);exchange.addExchangeCompleteListener(new ExchangeCompletionListener() {@Overridepublic void exchangeEvent(HttpServerExchange exchange, NextListener nextListener) {key.remove();nextListener.proceed();}});}exchange.dispatch(exchange.isInIoThread() ? SameThreadExecutor.INSTANCE : exchange.getIoThread(), clientHandler);}

可以很明显看到,如果target是null, 就走下一个handler 不再继续走代理逻辑了。

转载于:https://www.cnblogs.com/ljgeng/p/11240012.html

Undertow 实现反向代理相关推荐

  1. Marco's Java【Ngnix入门(二) 之反向代理及负载均衡】

    前言 能翻到这篇文章的朋友想必对Web服务器已经不陌生了,那么大家都用过哪些Web服务器服务器呢? 看过我SpringBoot系列文章的朋友,应该知道SpringBoot内置有三大服务器:Tomcat ...

  2. ATS 5.3.0在反向代理模式下实现正向代理功能方法

    以前,我在records.config中一般是配置成正向+反向的形式: 现在我打算改为反向代理模式,但是需要实现正向代理的功能: 同时在remap.config中配置 regex_map http:/ ...

  3. nginx反向代理原理及配置详解

    nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...

  4. Apache反向代理设置【转载】

    编译Apache时要进行的设置 ./configure --enable-mods-shared="all proxy" 1>修改 httpd.conf 文件中: LoadM ...

  5. http header头设置反向代理不缓存

    一:概念说明 Expries:网页的cache过期时间,到指定日期网页cache失效 Last-Modified:网页的最新更新时间 Cache-Control 缓存控制 no-cache:不缓存网页 ...

  6. Squid3反向代理安装与配置

    一.编译安装 下载 #wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABLE25.tar.gz //找到地址 #tar zxv ...

  7. nginx 反向代理,动静态请求分离,proxy_cache缓存及缓存清除

    一,nginx反向代理配置 #tomcat 显然就是用户访问www.wolfdream.com(需要设置本地localhost,将www.wolfdream.com指向nginx所在IP)的时候(或将 ...

  8. Linux下DNS轮询与Squid反向代理结合

    一.安装反向代理服务器 1.下载反向代理服务器软件采用squid,下载地址: http://www.squid-cache.org/Versions/v2/2.2/squid-2.2.STABLE5- ...

  9. squid,nginx,lighttpd反向代理的区别

    反向代理从传输上分可以分为2种: 1:同步模式(apache-mod_proxy和squid) 2:异步模式(lighttpd 和 nginx) 在nginx的文档说明中,提到了异步传输模式并提到它可 ...

  10. Nginx学习3:反向代理实例

    Nginx配置实例-反向代理1 目标 打开浏览器,在浏览器地址栏输入地址 www.123.com,跳转到 liunx 系统 tomcat 主页面中 准备工作 我们在官网下载好tomcat之后,直接将t ...

最新文章

  1. Django源码分析7:migrate命令的浅析
  2. 机器学习中的没有免费的午餐定律是什么?“没有免费的午餐”对你意味着什么?没有免费午餐定律定律能给数据科学家提供什么启示?
  3. ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available 错误解决方法
  4. linux错误:E212 can‘t open file for writing
  5. python pexpect模块详解_python pexpect模块
  6. java ipmitool_ipmitool使用手册
  7. mysql 多物理机_MySQL 5.6同一物理主机配置多实例
  8. top10开源docker开发工具
  9. ubuntu下搭建erlang编程环境
  10. ecshop商品下面显示销售量
  11. js requestAnimationFrame
  12. 万花筒写轮眼动态息屏_用了这么久的iPhone,才知道原来息屏也能录像
  13. 台式计算机液晶显示屏尺寸,台式电脑显示屏共有多少种尺寸?
  14. ShFileOperation函数详解
  15. python做生物信息学分析_Python从零开始第五章生物信息学①提取差异基因
  16. Android smali语法
  17. 搜索引擎提交入口总结
  18. 中石油 所罗门的宝藏
  19. java中的文件存储_File存储 - 文件存储
  20. 【matplotlib】画图基本函数 pyplot.barh 画水平柱状图

热门文章

  1. IP地址的分类及子网划分
  2. nyoj--325--zb的生日
  3. MVC 实体如何获取子集
  4. 异步任务利器Celery(一)介绍
  5. 关于 Maven 的插件maven-war-plugin
  6. LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决方案
  7. 转载一篇写的简单易懂的lvs用法
  8. rhel7.0安装篇
  9. ubuntu安装配置ssmtp
  10. CSocket实现端口扫描