2016-05-11 4 views
0

Ist es in einem Java HttpServlet möglich, Daten von einem anderen lokalen Dienst anzufordern, der die Header-Information der ursprünglichen Anforderung verwendet, ohne notwendigerweise Weiterleitung?Java-Servlet, das Daten vom lokalen Dienst anfordert

Zum Beispiel, ich habe 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 
    } 
} 

Schritt 1 das Problem ist hier. Der Zweck davon ist, dass ich in der Lage sein möchte, irgendeine Art von Logik auf den Daten durchzuführen, bevor es vollständig zurückgibt, aber nicht unbedingt Zugriff habe, die Änderungen auf dem Handler bei /foo/baz tun, um die Anstandsnatur der Dinge zu tun.

+2

Erstellen Sie ein neues HttpGet, füllen Sie es mit Kopfzeileninformationen aus der ursprünglichen Anfrage und senden Sie es an http: // localhost/foo/baz? –

Antwort

0

Mit HttpURLConnection und Ändern der Header, um eine Eigenschaft aus der ursprünglichen Anfrage aufzunehmen, konnte ich eine BufferedReader von der HTTP-Anfrage erhalten:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{ 
    // Step 1 
    String serverName = request.getLocalName(); 
    String contextPath = request.getContextPath(); 

    URL url = new URL("https://" + serverName + contextPath + "/baz"); 
    HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
    connection.setRequestProperty("Key Header", request.getHeader("Key Header")); 

    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

    // Step 2 
    ... // Do something with the data from the reader 

    // Step 3 
    ... // Write the data back using the response 
} 
1

Sie diese Antwort von mir können Sie eine HTTP-Anforderung erstellen: send get request

Darüber hinaus kann es erforderlich sein, die Request-Header mit einiger Vorsicht zu kopieren:

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", ""); 
} 
+0

Ich erkannte, dass ich nur eine bestimmte Eigenschaft des Headers kopieren musste. Ich habe allerdings eine Frage: Wie unterscheidet sich die 'HttpGet' und' HttpClient' Methode von einer 'GET' Anfrage von' HttpsURLConnection'? Ich poste meine Lösung hier in einer Sekunde, aber das ist es, was mir einfällt. – Aetylus

+1

@Aetylus - Ich habe die Klassen von Apache HTTP-Komponenten verwendet, weil sie einige zusätzliche Funktionen für die Bearbeitung des Hauptteils einer Anfrage/Antwort bereitstellen. Vielleicht reicht 'HttpsUrlConnection' für Ihre Aufgabe. Ich füge den Code der Methode 'setProxySpecificRequestHeaders()' zu meiner Antwort hinzu. – JimHawkins

Verwandte Themen