In meiner REST-Anwendung senden verwende ich diese Klasse Anfragen senden:Kann nicht die Ausnahme abfangen, wenn ich eine REST-Anfrage an einen HTTP-Server offline
public final class Utility {
private static Client client = ClientBuilder.newClient();
private Utility(){
}
public static <T> Response sendRequest(String URI, String method, T payload){
Response response = null;
WebTarget target = client.target(URI);
switch(method){
case "GET":
response = target.request().header("Content-type", "application/json").get();
break;
case "POST":
response = target.request().header("Content-type", "application/json").post(Entity.json(payload));
break;
case "PUT":
response = target.request().header("Content-type", "application/json").put(Entity.json(payload));
break;
case "DELETE":
response = target.request().header("Content-type", "application/json").delete();
break;
default:
throw new NotAllowedException("Invalid method type was given "
+ "to the Utility.sendRequest() method");
}
if(response == null){
throw new UnavailableServerException("The server at (" + URI + ") did not respond.");
}
return response;
}
}
Ich habe vor kurzem hatte die Idee, die ich behandeln mag Fälle, wenn ich eine Anfrage an einen Endpunkt sende, der nicht antworten kann. (Ich habe den grizzly http-Server dafür nicht gestartet). Ich habe gelernt, dass, wenn ich versuche, eine Anfrage an einen solchen Endpunkt zu senden, mein allgemeiner ExceptionMapper (der ExceptionMapper (ExceptionMapper) implementiert) ihn abfängt, und die Ausnahme war eine NullPointerException (NPE).
Also dachte ich, alles, was ich tun muss, ist einfach die Response an eine Variable auszulagern und vor dem Zurückgeben zu prüfen, ob es == null ist. Mit printfs und Debug-Modus sah ich das folgende Verhalten:
response == null
nicht wahr.catch(Exception e)
) mit try-catch-Blöcke innerhalb der Utility-Klasse und innerhalb der Ressource-Methode auch, ohne Erfolg.Ich habe versucht, herauszufinden, was wirft NPE in der javax.ws.rs.core.Response;
Dokumentation -> kein Erfolg. Ich habe keine Ideen:/(Btw UnavailableServerException
ist meine benutzerdefinierte Ausnahme auch.)
Auch was ist der richtige Weg zu überprüfen, ist die Anfrage erfolgreich, da der Null-Check offensichtlich keine gute Lösung.
EDIT: hier die stacktrace
javax.ws.rs.ProcessingException: Already connected
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:264)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.put(JerseyInvocation.java:326)
at eu.arrowhead.common.Utility.sendRequest(Utility.java:32)
at eu.arrowhead.core.gatekeeper.GatekeeperResource.GSDPoll(GatekeeperResource.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384)
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Already connected
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(Unknown Source)
at org.glassfish.jersey.client.internal.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:421)
at org.glassfish.jersey.client.internal.HttpUrlConnector.access$100(HttpUrlConnector.java:96)
at org.glassfish.jersey.client.internal.HttpUrlConnector$4.getOutputStream(HttpUrlConnector.java:384)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:194)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:262)
at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:816)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:545)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
... 37 more
EDIT2 ist:
@Provider
public class GenericExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception ex) {
ErrorMessage errorMessage = new ErrorMessage("Class: " + ex.getClass().toString() +
" Message: " + ex.getMessage(), 500, "No documentation yet.");
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(errorMessage)
.build();
}
}
Auch hier ist mein allgemeiner Ausnahme-Mapper, obwohl ich denke, das ist nicht Teil des Problems ist, anstatt dass in meinem Beispiel meine Anfrage 3 Server beinhaltet. Diese Anfrage wird an einen Online-Server gesendet, der etwas an einen zweiten Online-Server sendet (mit der gleichen Nutzungsklassenmethode), der eine dritte abfragt, die in meinem Test offline ist. Der 2. Server bricht die ProcessingException ab (soweit ich weiß, kann die OK-Antwort sein, wenn der 3. Server offline ist) und sendet meine benutzerdefinierte Ausnahme zurück. aber dann auf dem ersten Server kann irgendwie diese Ausnahme nicht zurück zu meinem Postman-Client senden, und eine generische NPE wird geworfen.
Ich werde versuchen, den Grund dafür morgen aber zu finden. Ich werde auch Jersey von 2.22.1 auf 2.23.1 aktualisieren.
versuchen Sie, Ihren Code in den 'try catch' Block zu setzen. Ich denke, wenn Server nicht verfügbar ist, wird HttpException ausgelöst. – Valijon
Bitte zeigen Sie den tatsächlichen Stacktrace –
Ich kann leider nicht wirklich einen Stacktrace zeigen. Selbst wenn ich meinen generischen Exception Mapper abmelde, ist das einzige, was ich im Postboten zurückbekomme, die Grizzly html Seite, ich glaube etwas maskiert den Stacktrace. @Valijon Ich habe das schon probiert, wie ich in der Post erwähnt habe, keine Ahnung, wieso geht das nicht. –