SpringBoot使用ProxyServlet实现HTTP反向代理


<dependency>
    <groupId>org.mitre.dsmiley.httpproxygroupId>
    <artifactId>smiley-http-proxy-servletartifactId>
    <version>1.11version>
dependency>


<dependency>
    <groupId>com.google.guavagroupId>
    <artifactId>guavaartifactId>
    <version>18.0version>
dependency>
# 设置代理
proxy:
	servlet_url: /proxybaidu/*
	target_url: https://www.baidu.com
@Configuration
 public class ProxyServletConfiguration {
     /**
      * 读取配置文件中路由设置
      */
    @Value("${proxy.servlet_url}")
     private String servlet_url;
    /**
      * 读取配置中代理目标地址
      */
     @Value("${proxy.target_url}")
    private String target_url;
 
    @Bean
     public Servlet createProxyServlet() {
         /** 创建新的ProxyServlet */
         return new ProxyServlet();
     }
 
    @Bean
     public ServletRegistrationBean proxyServletRegistration() {
         ServletRegistrationBean registrationBean = new ServletRegistrationBean(createProxyServlet(), servlet_url);
         //设置网址以及参数
         Map<String, String> params = ImmutableMap.of("targetUri", target_url, "log", "true");
        registrationBean.setInitParameters(params);
         return registrationBean;
    }

	/**
	 * fix springboot中使用proxyservlet的 bug.
	 *  https://github.com/mitre/HTTP-Proxy-Servlet/issues/83
	 *  https://stackoverflow.com/questions/8522568/why-is-httpservletrequest-inputstream-empty
	 * @param filter
	 * @return  关闭springboot 自带的 HiddenHttpMethodFilter 防止post提交的form数据流被提前消费
	 *
	 */
 	@Bean
  public FilterRegistrationBean registration(HiddenHttpMethodFilter filter) {
      FilterRegistrationBean registration = new FilterRegistrationBean(filter);
      registration.setEnabled(false);
     return registration;
  }
}
  • 测试:localhost:8080/proxybaidu/

    浏览器访问:localhost:8080/proxybaidu/ 就会被springboot获取,并代理成 https://www.baidu.com
    注意,如果访问:localhost:8080/proxybaidu/xxxxxx 就会被springboot获取,并代理成 https://www.baidu.com/xxxxxx

  • 也可以重新写个类,MyProxyServlet继承ProxyServlet
    在execute方法中添加日志,权限登录等相关的功能

    @Override
     protected HttpResponse execute(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
    HttpRequest proxyRequest) throws IOException {
        //设置header里的授权信息
        proxyRequest.setHeader("Authorization", "Basic " + getWebappBLoginAuth());
        HttpResponse response = super.doExecute(servletRequest, servletResponse, proxyRequest);
        
     //        设置跨域,暂时不用。
     //        String origin = servletRequest.getHeader("origin");
     //        response.setHeader("Access-Control-Allow-Origin", origin);
     //         response.setHeader("Access-Control-Allow-Credentials", "true");
     //        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
     //        response.setHeader("Access-Control-Allow-Headers",
    //                "Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin" +
     //                        ",User-Agent,X-Mx-ReqToken,X-Requested-With");
             return response;
         }
    

你可能感兴趣的:(后端技术,spring,boot,http,servlet)