2017-04-04 1 views
16

Ich mache einen REST-Aufruf von Java zu einem externen System. Wenn es Verbindungsunterbrechungen gibt, wie wenn das externe System offline geht, brauche ich einen Listener, um dies zu erkennen und entsprechende Aktionen auszuführen. Bitte lassen Sie mich wissen, ob ich dies in Java erreichen kann. Vorzugsweise in Java 8.HTTP-Unterbrechung in Java erkennen

Derzeit bekomme ich keine Ausnahme, wenn ich in eine solche Situation komme. Ich mit der unten gezeigten Code zur Zeit

Client client = ClientBuilder.newClient(); 
    WebTarget target = client.target(HOSTNAME); 
    Invocation.Builder requestBuilder; 

    requestBuilder = target.path(URL).request(MediaType.APPLICATION_JSON) 
               .header(HEADER_AUTHORIZATION, AUTH_TOKEN);  
    Response response = null; 
    if (HTTP_POST.equalsIgnoreCase(method)) { 
     try{ 
     response = requestBuilder.post(Entity.entity(message, MediaType.APPLICATION_JSON_TYPE)); 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
    } else if (HTTP_GET.equalsIgnoreCase(method)) { 
     response = requestBuilder.get(); 
    } 

    String executeMessage = null; 
    if(response != null){ 
     if (response.getStatus() == 200) { 
      executeMessage = response.readEntity(String.class);   
      return new JSONObject(executeMessage); 
     } else { 
      executeMessage = response.readEntity(String.class); 
      final JSONObject status = new JSONObject(); 
      status.put(STATUS_CODE, response.getStatus()); 
      status.put(STATUS_INFO, response.getStatusInfo()); 
      status.put("response", executeMessage); 
      final JSONObject error = new JSONObject(); 
      error.put(ERROR, status); 
      return error; 
     } 
    } 
+1

Sie erhalten eine IOException, die Sie fangen müssen, also geben Sie einen speziellen Code ein. –

+1

Weitere Details darüber, welches Framework Sie verwenden, um die HTTP-Anfrage zu erstellen, und ein Code-Snippet, aus dem der aufrufende Code besteht, helfen Ihnen, nützlichere Antworten zu erhalten. –

+0

@Michael Peyper - Ich habe mit dem Code aktualisiert. Steve Smith - Derzeit bekomme ich keine Ausnahme, System wartet auf die Antwort. –

Antwort

0

Sie könnten Ihren eigenen Listener erstellen und machen Sie Ihre Http ruft Asynchron mit den an die aufrufende Klasse übergeben Ergebnisse zurück, wenn die HTTP-Antwort/Fehler bereit ist. Zum Beispiel (mit Fehlern):

Eine Schnittstelle, die Ihre wird Hauptklasse implementieren und Ihre Http Client wird die Verwendung von ...

public interface MyHttpListener { 
    public httpComplete(MyHttpResults results); 
} 

Implementierung in Ihrer Hauptklasse machen.

public MyClass implements MyHttpListener { 

    public void processHttpRequests(){ 
     for(int i=0; i<10; i++){ 
     // instantiate your Http Client class 
     HttpClient client = new HttpClient(); 

     // register the listener 
     client.addHttpListener(this); 

     // execute whatever URL you want and you are notified later when complete 
     client.executeRequest("http://whatever"); 
    } 
    } 

    public httpRequestComplete(MyHttpResults results) { 
    // do something with the results 
    results.getResponseCode(); 
    results.getRawResponse(); 
    results.whatever(); 
    } 

}

Add-Methode, um Ihre Httpclient Zuhörer zu akzeptieren

public class MyHttpClient { 
    List<MyHttpListener> httpListenerList = new ArrayList(); 

    // register listeners 
    public void addHttpListener(MyHttpListener listener){ 
    httpListenerList.add(listener); 
    } 

    // this is the method that processes the request 
    public void executeRequest(String url) { 

    // do whatever you were doing previously here 

    // optional POJO to wrap the results and/or exceptions 
    MyHttpResults results = new MyHttpResults(); 
    results.withResponseCode(response.getResponseCode()); 
    results.withResponse(responseAsString); 
    results.withException(ex); 
    results.withWhatever(whatever); 

    // notify listeners 
    notify(results); 

    } 

    public void notify(MyHttpResults results){ 
     // notify listeners 
     for(MyHttpListener listener : httpListenerList){ 
     listener.httpComplete(results); 
     } 
    } 


} 
1

Wenn Sie Frühlings-Boot verwenden, können Sie eine deklarative REST-Client Feign genannt versuchen:

@FeignClient(url = "example.com", fallback = YourTestFeignClient.YourTestFeignClientFallback.class) 
public interface YourTestFeignClient { 

    @RequestMapping(method = RequestMethod.POST, value = "/example/path/to/resource/{id}") 
    YourTestResponse requestExternalResource(@RequestParam("id") Long id, SomeRequestDTO requestDTO); 

    @Component 
    public static class YourTestFeignClientFallback implements YourTestFeignClient { 

     @Override 
     public YourTestResponse requestExternalResource(Long id, SomeRequestDTO requestDTO) { 
      YourTestResponse testResponse = new YourTestResponse(); 
      testResponse.setMessage("Service unavailable"); 
      return testResponse; 
     } 

    } 
} 

Alle Sie müssen hier YourTestFeignClient in Ihrem Code ein injizieren d Rufen Sie die Methode requestExternalResource darauf auf. Dies ruft POST example.com/example/path/to/resource/34 mit JSON-Körper aus SomeRequestDTO. Falls eine Anfrage fehlschlägt, wird eine Fallback-Methode innerhalb von YourTestFeignClientFallback aufgerufen, die dann einige Standarddaten zurückgibt.

0

Wenn Sie ständig überprüfen möchten, ob der externe REST-Dienst offline ist, müssen Sie eine periodische Ping-Anfrage erstellen. Jede Antwort bedeutet, dass der Dienst online ist. Wenn während einer gewissen Zeit keine Antwort erfolgt, bedeutet dies, dass etwas nicht stimmt.

Das Problem Sie konfrontiert sind, dass Java steigt von TCP Socket connect Verfahren blockiert und Java Standard-Buchse verbinden Timeout 0 ist, die tatsächlich Unendlichen ist, wie es in javadoc gesagt wird.

Das bedeutet, dass Sie standardmäßig keine Antwort erhalten, wenn der Dienst offline ist.

Die einzige korrekte und einfache Option hier ist ein Timeout zu setzen. In Ihrem Fall wäre der einfachste Weg, Jersey Client Eigenschaft Setup zu verwenden, wie folgt aus:

Client client = ClientBuilder.newClient(); 
// One second timeout may not be a really good choice unless your network is really fast 
client.property(ClientProperties.CONNECT_TIMEOUT, 1000); 

Und nur in diesem Fall erhalten Sie eine Ausnahme erhalten, die darauf hindeuten, wird, dass REST Dienst, den Sie ping versuchen werden, ist keine Verbindungen akzeptieren.

Timeout mit Vorsicht entsprechend den tatsächlichen Netzwerkfähigkeiten einstellen, in einigen Fällen sollte es mehr als 5 oder sogar 15 Sekunden dauern (z. B. WiFi und GPRS-Verbindungen).

Verwandte Themen