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-servlet
Similar 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.POST
The type of parameter requested and carried x-www-form-urlencoded
This 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-urlencoded
When 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 inheritanceProxyServlet
And rewritenewProxyRequestWithEntity
The 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; }
SolrProxyServletConfiguration
You also need to reset the useProxyServlet
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyProxyServlet(), ("servlet_url"));
This is what I'm using smiley-http-proxy-servlet
I 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.