JAX-RS Exception Handling

internet

Top Contributor
Hallo,

ich bin mir nicht so sicher, wie ich das Exception Handling bei einem Webservice aufbauen möchte.
Generell möchte ich ja die Response Code zurückgeben.
Wenn zum Beispiel keine Daten gefunden werden, brauche ich keinen Stacktrace in meinem Server, lediglich der Client benötigt dann eben den entsprechenden Reponse Code...

Also sowas wie:
Java:
ErrorMessage errorMessage = new ErrorMessage("No Customer found", Status.NOT_FOUND.getStatusCode());
                return Response.status(Status.NOT_FOUND).entity(errorMessage).type(MediaType.APPLICATION_JSON)
                        .build();

Meine Google Recherche hat ergeben, dass ich auch so die Exceptions schmeißen kann:
Java:
public class DataNotFoundException extends WebApplicationException {

    private static final long serialVersionUID = 5482195260668796087L;

    public DataNotFoundException() {
    }

    public DataNotFoundException(String message) {
        super(message);
    }
}

Java:
@Provider
public class DataNotFoundExceptionMapper implements ExceptionMapper<DataNotFoundException> {

    @Override
    public Response toResponse(DataNotFoundException ex) {

        ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), Status.NOT_FOUND.getStatusCode());

        return Response.status(Status.NOT_FOUND).entity(errorMessage)
                .build();
    }

}

Und dann im Webservice hier schmeißen:

Java:
@GET
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response findById(@PathParam("id") Long id) {

            Customer customer = customerService.findCustomerById(id);

        if(customer == null)
            throw new DataNotFoundException();
        
            return Response.ok(customer, MediaType.APPLICATION_JSON)
                    .build();

        return Response.ok().build();
    }

Das läuft ja auch alles.
Nur was ich dann habe ist, dass ich einen Stacktrace in meinem Webserver bekomme. Aber eigentlich brauche ich nur den Reponse Code.

Wie baue ich das richtig?
 
sondern z.B. mit Optional arbeiten, um ein "keine Daten" sichtbarer zu machen.

Was meinst du mit "Optional" arbeiten?

Ne, es ist ja eigentlich kein Fehler. Es gibt einfach keine Daten für die Abfrage für den Client.
Also es ist kein Fehler, auf welchen ich (als Betreiber des Webservice) aufmerksam gemacht werden muss, sodass bei mir im Logfile ein Eintrag entsteht oder o.ä.

Ich bin mir nicht sicher, ob ich es richtig verstehe, aber ich würde anstatt diesem Code im Webservice:
Java:
if(customer == null)
return Response.status(Status.NOT_FOUND).entity(errorMessage)
                .build();

Das schmeißen
Java:
if(customer == null)
throw new DataNotFoundException();

Was dann im Endeffekt auch nur das schmeißt:
Java:
return Response.status(Status.NOT_FOUND).entity(errorMessage)
                .build();

Prinzipiell geht das und der Client bekommt den 404 Reponse zurück, aber ich bekomme im Server zudem noch ein Stacktrace etc. was ich ja eigentlich nicht brauche / möchte.
 
Was meinst du mit "Optional" arbeiten?

Ne, es ist ja eigentlich kein Fehler.
Dann würde ich auch keine Exception nutzen 🙂

Stattdessen einfach sowas (als pseudocode):

Java:
if (keine daten) {
    return Response.status(Status.NOT_FOUND).entity(errorMessage) .build()
}
return Response.ok(daten, MediaType.APPLICATION_JSON).build();
 
findXXX-Methoden deuten zumindest nach meinem Verständnis darauf hin, dass von Parametern ausgegangen wird, die kein Ergebnis liefern. Suche ich nach einem Kunden mit der ID 4, gibt es zwei Optionen: Kunde wurde gefunden, oder eben nicht. Die findXXX-Methode kann also ein Optional<Customer> liefern. Dann könnte der Code so geschrieben werden:
Java:
return customerService.findCustomerById(id)
        .map(customer -> Response.ok(customer))
        .orElse(Response.status(Status.NOT_FOUND).entity(errorMessage))
        .build();

Nachtrag: falschen Knopf erwischt...

oder auch
Java:
Optional<Customer> customer = customerService.findCustomerById(id);
if (customer.isPresent()) {
    retun Response.ok(customer.get()).build();
}
return Reponse.status(Status.NOT_FOUND).entity(errorMessage).build();
 

Zurück
Oben