• 通过ProxyServlet实现可编程的反向代理


    说道反向代理,可能首先想到的就是nginx。不过在我们的需求中,对于转发过程有更多需求:

    • 需要操作session,根据session的取值决定转发行为
    • 需要修改Http报文,增加Header或是QueryString

    第一点决定了我们的实现必定是基于Servlet的。jetty提供的ProxyServlet就可以满足我们的要求,ProxyServlet直接继承自HttpServlet,采用异步的方式调用内部服务器,因材效率上不会有什么问题,并且各种可重载的函数也提供了比较强大的定制机制。

    首先确保当前Servlet版本到达3.1,这个版本才能提供ProxyServlet所要求的异步功能。jetty9搭载的Servlet版本就是3.1,构建的时候引用它就好。其次是在Servlet的配置中打开异步功能:

    <servlet>
        <servlet-name>proxyservlet</servlet-name>
        <servlet-class>net.narcissu5.SimpleProxyServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>

    然后是实现我们的类,从ProxyServlet继承:

    package net.narcissu5;
    
    import org.eclipse.jetty.client.api.Request;
    import org.eclipse.jetty.proxy.ProxyServlet;
    
    import javax.servlet.http.HttpServletRequest;
    import java.net.URI;
    import java.net.URISyntaxException;
    
    public class SimpleProxyServlet extends ProxyServlet {
        @Override
        protected Request addViaHeader(Request proxyRequest) {
            proxyRequest.header("Basic","123456");
            return super.addViaHeader(proxyRequest);
        }
    
        @Override
        protected URI rewriteURI(HttpServletRequest request) {
            URI uri = null;
            try{
                if(request.getQueryString() == null){
                    uri = new URI("http://192.168.235.129:8080");
                } else {
                    uri = new URI("http://192.168.235.129:8080?" + request.getQueryString());
                }
            } catch (URISyntaxException e){
    
            }
            return uri;
        }
    }

    当然rewriteURI中可以有更复杂的逻辑,既然都已经进入到了这里,转发规则就不是什么问题了。最后注意下jetty class load的问题。jetty 9 使用JavaEE规范,先加载用户类再加载服务器类,因此引用的jetty-proxy.jar如果设置为provide(也就是不打包进入war)的话会出现ClassNotFound异常。通常的做法(感谢StackOverflow)是设置为编译时依赖:

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-proxy</artifactId>
        <version>9.1.5.v20140505</version>
    </dependency>

    这样它就普通的Servlet没什么区别了,虽然war最后会大那么一点点~~

  • 相关阅读:
    dart中Map类型详解
    洛谷P1582 倒水(二进制)
    maven依赖 临时转阿里云镜像
    java jdbc 连接数据库
    java 常用类
    java 异常处理
    java 对象 this static 封装
    java 面对对象 内存分析
    团队开发 git
    java 代码块
  • 原文地址:https://www.cnblogs.com/narcissu5/p/3720029.html
Copyright © 2020-2023  润新知