diff --git a/pom.xml b/pom.xml index 7a39f62c..918a92f2 100644 --- a/pom.xml +++ b/pom.xml @@ -122,6 +122,11 @@ jersey-container-servlet ${jersey3-version} + + org.glassfish.jersey.ext + jersey-bean-validation + ${jersey3-version} + com.fasterxml.jackson.datatype diff --git a/smart-connector-rest-server/pom.xml b/smart-connector-rest-server/pom.xml index b5fab450..f4d853f0 100644 --- a/smart-connector-rest-server/pom.xml +++ b/smart-connector-rest-server/pom.xml @@ -70,6 +70,10 @@ org.glassfish.jersey.containers jersey-container-servlet + + org.glassfish.jersey.ext + jersey-bean-validation + diff --git a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/JsonExceptionMapper.java b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/JsonExceptionMapper.java index c9604e92..205d00b5 100644 --- a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/JsonExceptionMapper.java +++ b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/JsonExceptionMapper.java @@ -1,12 +1,13 @@ package eu.knowledge.engine.rest.api; +import com.fasterxml.jackson.core.JsonProcessingException; + +import eu.knowledge.engine.rest.model.ResponseMessage; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.Provider; -import com.fasterxml.jackson.core.JsonProcessingException; - /** * Since apparently Jersey gives a status 500 response when it encounters * unexpected input in request bodies, this exception mapper maps those @@ -16,10 +17,11 @@ public class JsonExceptionMapper implements ExceptionMapper { @Override public Response toResponse(JsonProcessingException exception) { - return Response - .status(Response.Status.BAD_REQUEST) - .entity(exception.getOriginalMessage()) - .type(MediaType.TEXT_PLAIN) - .build(); + + var response = new ResponseMessage(); + response.setMessageType("error"); + response.setMessage(exception.getClass().getSimpleName() + ": " + exception.getOriginalMessage()); + + return Response.status(Response.Status.BAD_REQUEST).entity(response).type(MediaType.APPLICATION_JSON).build(); } } diff --git a/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/ValidationExceptionMapper.java b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/ValidationExceptionMapper.java new file mode 100644 index 00000000..93da1f7c --- /dev/null +++ b/smart-connector-rest-server/src/main/java/eu/knowledge/engine/rest/api/ValidationExceptionMapper.java @@ -0,0 +1,34 @@ +package eu.knowledge.engine.rest.api; + +import eu.knowledge.engine.rest.model.ResponseMessage; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; + +/** + * Validation errors by default are returned as plain text and this class maps + * those errors to our {@link ResponseMessage}. + */ +@Provider +public class ValidationExceptionMapper implements ExceptionMapper { + @Override + public Response toResponse(ConstraintViolationException exception) { + + var response = new ResponseMessage(); + response.setMessageType("error"); + response.setMessage(exception.getClass().getSimpleName() + ": " + prepareMessage(exception)); + + return Response.status(Response.Status.BAD_REQUEST).entity(response).type(MediaType.APPLICATION_JSON).build(); + } + + private String prepareMessage(ConstraintViolationException exception) { + StringBuilder message = new StringBuilder(); + for (ConstraintViolation cv : exception.getConstraintViolations()) { + message.append(cv.getPropertyPath() + " " + cv.getMessage() + "\n "); + } + return message.toString(); + } +}