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();
+ }
+}