Java Servlet 从本地服务请求数据

标签 java servlets

在 Java 中 HttpServlet ,是否可以使用原始请求的 header 信息从另一个本地服务请求数据,而不必转发?

例如,我有 FooBar.java :

// Handles the url at /foo/bar and can be accessed at http://localhost/foo/bar
public class FooBar extends HttpServlet
{
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
   {
      Object data = ...                             // 1. Retrieve data at http://localhost/foo/baz utilizing the current request's header
      Object newData = doSomething(data);           // 2. Process the data
      response.getWriter().write(newData.toString); // 3. Return the processed data
   }

   private Object doSomething(Object data)
   {
      // Perform some business logic
   }
}

第 1 步是这里的问题。这样做的目的是,我希望能够在完全返回数据之前对数据执行某种逻辑,但不一定有权在/foo/baz处的处理程序上进行更改。遵循事物的正当本质。

最佳答案

您可以使用我的这个答案来创建 HTTP 请求:send get request

此外,可能需要小心地复制请求 header :

private static final Set forbiddenCopyHeaders = new HashSet<>(Arrays.asList(new String[]{
        "connection"
        , "transfer-encoding"
        , "content-length"    // POST kann zu Status 500 führen, wenn die content-length kopiert wird
        , "via"
        , "x-forwarded-for"
        , "x-forwarded-host"
        , "x-forwarded-server"
}));

private void copyRequestHeaders(HttpServletRequest customerRequest, HttpRequestBase internRequest) throws
        HttpException
{

    Enumeration<String> headerNames = customerRequest.getHeaderNames();
    String connectionHeader = customerRequest.getHeader("connection");

    while (headerNames.hasMoreElements())
    {
        String headerName = headerNames.nextElement();

        boolean copyAllowed = !forbiddenCopyHeaders.contains(headerName.toLowerCase()) &&
                !StringUtils.containsIgnoreCase(connectionHeader, headerName);

        if (copyAllowed)
        {
            Enumeration<String> values = customerRequest.getHeaders(headerName);
            while (values.hasMoreElements())
            {
                internRequest.addHeader(headerName, values.nextElement());
            }
        }
    }

    setProxySpecificRequestHeaders(customerRequest, internRequest);
}


private void setProxySpecificRequestHeaders(HttpServletRequest customerRequest,
                                            HttpRequestBase internRequest) throws HttpException
{
    String serverHostName = "doorman";
    try
    {
        serverHostName = InetAddress.getLocalHost().getHostName();
    }
    catch (UnknownHostException e)
    {
        logger.error("Couldn't get the hostname needed for headers x-forwarded-server and Via", e);
    }

    String originalVia = customerRequest.getHeader("via");
    StringBuilder via = new StringBuilder("");
    if (originalVia != null)
    {
        if (originalVia.contains(serverHostName))
        {
            logger.error("This proxy has already handled the Request, will abort.");
            throw new HttpException("Request has a cyclic dependency on this proxy.");
        }
        else
        {
            via.append(originalVia).append(", ");
        }
    }
    via.append(customerRequest.getProtocol()).append(" ").append(serverHostName);

    internRequest.addHeader("via", via.toString());
    internRequest.addHeader("x-forwarded-for", customerRequest.getRemoteAddr());
    internRequest.addHeader("x-forwarded-host", customerRequest.getServerName());
    internRequest.addHeader("x-forwarded-server", serverHostName);

    internRequest.addHeader("accept-encoding", "");
}

关于Java Servlet 从本地服务请求数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37172057/

相关文章:

jsf - Primefaces 文件上传和 session 超时

java - Spring MVC 不会从链接更改区域设置

java - 如何创建一个抽象适配器类,强制子类调用构造函数中的特定方法

java - RabbitMQ Java客户端: What happens when a RuntimeException is thrown inside a consumer's handleDelivery() method?

java - 从列表或两个不同实体动态查询

java - 您如何为 Java servlet 编写单元测试?

java - Java TreeSet 中的给定元素处于什么级别?

java - 为什么泛型方法更改了赋值中的参数化类型?

javascript - $document.ready() 在 servlet 中不工作

java - 嵌入式 Jetty 服务器挂起