SoFunction
Updated on 2025-03-04

nginx reverse proxy java project method

nginx reverse proxy java project

server
{
    listen 80;
    server_name ***.***.com;
    
    location / {
    	proxy_pass http://127.0.0.1:8686;
  	}
    
    #One-click application for SSL certificate verification directory related settings    location ~ \.well-known{
        allow all;
    }
    
    access_log  /www/wwwlogs/***.***.;
    error_log  /www/wwwlogs/***.***.;
}

It's very simple, the core is proxy_pass

The pitfall of Java implementing reverse proxy

The company is engaged in vehicle Internet of Things related services and needs a gateway system to analyze the packets uploaded by the device. Recently, I changed a new open source gateway system, which integrates some API interfaces for device operations. Since the gateway system cannot be external, another system needs to be authenticated and reverse proxyed to the gateway's API interface, similar to the reverse proxy of Nginx.

After searching online for a long time, I foundsmiley-http-proxy-servletSimilar functions can be implemented and the implementation is very simple. The implementation steps are as follows:

Import smiley-http-proxy-servletMaven dependency

<dependency>
    <groupId></groupId>
    <artifactId>smiley-http-proxy-servlet</artifactId>
    <version>1.12.1</version>
</dependency>

Write the proxy's prefix and destination address in the configuration file

proxy:
    solr:
        servlet_url: /proxy/*
        target_url: http://solrserver:8983/proxy

Write configuration classes

@Configuration
public class SolrProxyServletConfiguration implements EnvironmentAware {

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        Properties properties= (Properties) ();
        // Set proxy prefix        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ProxyServlet(), ("servlet_url"));
        // Set the proxy target address        (ProxyServlet.P_TARGET_URI, ("target_url"));
        // Set whether to print logs        (ProxyServlet.P_LOG, ("logging_enabled", "false"));
        return servletRegistrationBean;
    }

    private BindResult bindResult;

    @Override
    public void setEnvironment(Environment environment) {
        Iterable sources = (environment);
        Binder binder = new Binder(sources);
        BindResult bindResult = ("", );
         = bindResult;
    }
}

Assume that the current proxy server address is 127.0.0.1:8001, when accessing http://127.0.0.1:8001/proxy/test, the request is back to be forwarded to http://solrserver:8983/proxy/test, so we implement a requested proxy.

At that time, I was happy to think that the test was completed and I found that I was using it at that time.POSTThe type of parameter requested and carried x-www-form-urlencodedThis will cause the request to time out. After searching on Baidu for a long time, I couldn't find a solution, so I thought about going to the GitHub homepage of this project to see if any masters encountered this problem.

When I use x-www-form-urlencodedWhen searching for keywords in issues, it was really easy to find that some big shots also encountered this problem.

The reason for this problem is that there are too many filters in SpringBoot, which causes ResponseBody to be consumed in advance and cannot be returned to the client.

Under this issue, a big guy proposed a solution, which is inheritanceProxyServletAnd rewritenewProxyRequestWithEntityThe method, the code is as follows:

  protected HttpRequest newProxyRequestWithEntity(
      String method, String proxyRequestUri, HttpServletRequest servletRequest) throws IOException {
    HttpEntityEnclosingRequest eProxyRequest =
        new BasicHttpEntityEnclosingRequest(method, proxyRequestUri);

    String contentType = ();

    boolean isFormPost =
        (contentType != null
            && ("application/x-www-form-urlencoded")
            && "POST".equalsIgnoreCase(()));

    if (isFormPost) {
      List<NameValuePair> queryParams = ();
      String queryString = ();
      if (queryString != null) {
        queryParams = (queryString, Consts.UTF_8);
      }

      Map<String, String[]> form = ();
      List<NameValuePair> params = new ArrayList<>();

      OUTER_LOOP:
      for (Iterator<String> nameIterator = ().iterator(); (); ) {
        String name = ();

        // skip parameters from query string
        for (NameValuePair queryParam : queryParams) {
          if ((())) {
            continue OUTER_LOOP;
          }
        }

        String[] value = (name);
        if ( != 1) {
          throw new RuntimeException("expecting one value in post form");
        }
        (new BasicNameValuePair(name, value[0]));
      }
      (new UrlEncodedFormEntity(params, "UTF-8"));

    } else {
      (
          new InputStreamEntity((), getContentLength(servletRequest)));
    }
    return eProxyRequest;
  }

SolrProxyServletConfigurationYou also need to reset the useProxyServlet

ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyProxyServlet(), ("servlet_url"));

This is what I'm using smiley-http-proxy-servletI will share with you any other pitfalls encountered during the subsequent use.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.