Forward HttpServletRequest to a different server

前端 未结 5 1607
星月不相逢
星月不相逢 2021-01-31 15:24

I got a HttpServletRequest request in my Spring Servlet which I would like to forward AS-IS (i.e. GET or POST content) to a different server.

What would be

5条回答
  •  迷失自我
    2021-01-31 16:25

    Discussions of whether you should do forwarding this way aside, here's how I did it:

    package com.example.servlets;
    
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Enumeration;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.example.servlets.GlobalConstants;
    
    @SuppressWarnings("serial")
    public class ForwardServlet extends HttpServlet {
    
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
            forwardRequest("GET", req, resp);
        }
    
        @Override
        public void doPost(HttpServletRequest req, HttpServletResponse resp) {
            forwardRequest("POST", req, resp);
        }
    
        private void forwardRequest(String method, HttpServletRequest req, HttpServletResponse resp) {
            final boolean hasoutbody = (method.equals("POST"));
    
            try {
                final URL url = new URL(GlobalConstants.CLIENT_BACKEND_HTTPS  // no trailing slash
                        + req.getRequestURI()
                        + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod(method);
    
                final Enumeration headers = req.getHeaderNames();
                while (headers.hasMoreElements()) {
                    final String header = headers.nextElement();
                    final Enumeration values = req.getHeaders(header);
                    while (values.hasMoreElements()) {
                        final String value = values.nextElement();
                        conn.addRequestProperty(header, value);
                    }
                }
    
              //conn.setFollowRedirects(false);  // throws AccessDenied exception
                conn.setUseCaches(false);
                conn.setDoInput(true);
                conn.setDoOutput(hasoutbody);
                conn.connect();
    
                final byte[] buffer = new byte[16384];
                while (hasoutbody) {
                    final int read = req.getInputStream().read(buffer);
                    if (read <= 0) break;
                    conn.getOutputStream().write(buffer, 0, read);
                }
    
                resp.setStatus(conn.getResponseCode());
                for (int i = 0; ; ++i) {
                    final String header = conn.getHeaderFieldKey(i);
                    if (header == null) break;
                    final String value = conn.getHeaderField(i);
                    resp.setHeader(header, value);
                }
    
                while (true) {
                    final int read = conn.getInputStream().read(buffer);
                    if (read <= 0) break;
                    resp.getOutputStream().write(buffer, 0, read);
                }
            } catch (Exception e) {
                e.printStackTrace();
                // pass
            }
        }
    }
    

    Obviously this could use a bit of work with regard to error handling and the like but it was functional. I stopped using it, however, because it was easier in my case to make calls directly to the CLIENT_BACKEND than to deal with cookies, auth, etc. across two distinct domains.

提交回复
热议问题