/** * Test to see that the message "Got it!" is sent in the response. */ @Test public void testGetItValidationError() { Response resp = target().path("/myresource/id") .queryParam("key1", "2") .queryParam("key2", "") .request(MediaType.APPLICATION_JSON_TYPE).get(); int code = resp.getStatus(); ParsecErrorResponse err = resp.readEntity(new GenericType<ParsecErrorResponse<ValidationError>>() { }); assertEquals(code, BAD_REQUEST.getStatusCode()); assertValidationErrorEquals( err, 40001, "constraint violation validate error unittest", Arrays.asList("MyResource.getIt.namedValue1", "MyResource.getIt.namedValue2", "MyResource.getIt.value3") ); }
@Test public void testPostItValidationError() { MyDto dto = new MyDto(); MySubDto subDto = new MySubDto(); dto.setSubClass(subDto); Response resp = target().path("/myresource/id") .request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.json(dto)); int code = resp.getStatus(); ParsecErrorResponse err = resp.readEntity(new GenericType<ParsecErrorResponse<ValidationError>>(){}); assertEquals(code, BAD_REQUEST.getStatusCode()); assertValidationErrorEquals( err, 40001, "constraint violation validate error unittest", Arrays.asList("MyResource.postIt.dto.subClass.nickname", "MyResource.postIt.dto.firstName", "MyResource.postIt.value1", "MyResource.postIt.dto.lastName", "MyResource.postIt.dto.subClass.birthday") ); }
@Override public Response toResponse(ValidationException e) { ApiErrorCode errorCode = ApiErrorCode.PARAM_ERROR; StringBuffer errorMsgBuf = new StringBuffer(); final ConstraintViolationException cve = (ConstraintViolationException) e; List<ValidationError> errors = ValidationHelper.constraintViolationToValidationErrors(cve); for (ValidationError error : errors) { errorMsgBuf.append(error.getMessage()).append(";"); } String errorMsg = errorMsgBuf.toString(); if (StringUtils.isBlank(errorMsg)) { errorMsg = IMConstant.MSG_PARAM_ERROR; } String requestId = RequestContext.get("requestId"); ApiErrorCodeException errorCodeException = new ApiErrorCodeException(requestId, errorCode, errorMsg, e); logger.error(requestId, errorCodeException); return RestResult.failure(requestId, errorCode.errorCode, errorMsg); }
/** * assert parsec error response */ private void assertValidationErrorEquals( ParsecErrorResponse parsecError, int expectErrCode, String expectMessage, List<String> expectPaths) { assertEquals(parsecError.getError().getCode(), expectErrCode, "error code not equals"); assertEquals(parsecError.getError().getMessage(), expectMessage, "error message not equals"); assertEquals(parsecError.getError().getDetail().size(), expectPaths.size(), "error detail count not equals"); List<String> errPaths = new ArrayList<>(); for (Object obj : parsecError.getError().getDetail()){ errPaths.add(((ValidationError) obj).getPath()); } assertEqualsNoOrder(errPaths.toArray(), expectPaths.toArray(), "error paths not equals"); }
private Set<String> getValidationMessageTemplates(final List<ValidationError> errors) { final Set<String> templates = new HashSet<>(); for (final ValidationError error : errors) { templates.add(error.getMessageTemplate()); } return templates; }
@Override public Response toResponse(final ValidationException exception) { if (exception instanceof ConstraintViolationException) { LOGGER.log(Level.FINER, LocalizationMessages.CONSTRAINT_VIOLATIONS_ENCOUNTERED(), exception); final ConstraintViolationException cve = (ConstraintViolationException) exception; final Response.ResponseBuilder response = Response.status(getStatus(cve)); // Entity final List<Variant> variants = Variant.mediaTypes( MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE).build(); final Variant variant = request.get().selectVariant(variants); if (variant != null) { response.type(variant.getMediaType()); } else { /* * default media type which will be used only when none media type from {@value variants} is in * accept header of original request. */ response.type(MediaType.TEXT_PLAIN_TYPE); } response.entity( new GenericEntity<List<ValidationError>>( getEntity(cve.getConstraintViolations()), new GenericType<List<ValidationError>>() {}.getType() ) ); return response.build(); } else { LOGGER.log(Level.WARNING, LocalizationMessages.VALIDATION_EXCEPTION_RAISED(), exception); return Response.serverError().entity(exception.getMessage()).build(); } }
private List<ValidationError> getEntity(final Set<ConstraintViolation<?>> violations) { final List<ValidationError> errors = new ArrayList<ValidationError>(); for (final ConstraintViolation<?> violation : violations) { errors.add(new ValidationError(violation.getMessage(), violation.getMessageTemplate(), getPath(violation), getInvalidValue(violation.getInvalidValue()))); } return errors; }
/** * Accepts the result from one of the many validation methods available and * returns a List of ValidationErrors. If the size of the List is 0, no errors * were encounter during validation. * * Usage: * <pre> * Validator validator = getValidator(); * List<ValidationError> errors = contOnValidationError( * validator.validateProperty(myObject, "uuid"), * validator.validateProperty(myObject, "name") * ); * // If validation fails, this line will be reached. * </pre> * * @param violationsArray a Set of one or more ConstraintViolations * @return a List of zero or more ValidationErrors * @since 1.0.0 */ @SafeVarargs protected final List<ValidationError> contOnValidationError(final Set<ConstraintViolation<Object>>... violationsArray) { final List<ValidationError> errors = new ArrayList<>(); for (Set<ConstraintViolation<Object>> violations : violationsArray) { for (ConstraintViolation violation : violations) { if (violation.getPropertyPath().iterator().next().getName() != null) { final String path = violation.getPropertyPath() != null ? violation.getPropertyPath().toString() : null; final String message = violation.getMessage() != null ? StringUtils.removeStart(violation.getMessage(), path + ".") : null; final String messageTemplate = violation.getMessageTemplate(); final String invalidValue = violation.getInvalidValue() != null ? violation.getInvalidValue().toString() : null; final ValidationError error = new ValidationError(message, messageTemplate, path, invalidValue); errors.add(error); } } } return errors; }
@POST @Compress @Consumes(MediaType.APPLICATION_JSON) @Produces({APPLICATION_JSON, APPLICATION_XML}) @ApiOperation( code = 201, value = "Add a new book", response = Book.class ) @ApiResponses({ @ApiResponse( code = 201, message = "Book created successfully", response = Book.class, responseHeaders = @ResponseHeader( name = "Location", description = "URL of the newly created book", response = String.class ) ), @ApiResponse( code = 400, message = "Bad request", response = ValidationError.class ), @ApiResponse( code = 401, message = "'Authorization' header is missing or wrong username/password", response = ErrorResponse.class, responseHeaders = @ResponseHeader( name = "WWW-Authenticate", description = "Defines the authentication method that should be used to gain access to a resource.", response = String.class ) ), @ApiResponse( code = 500, message = "Internal Server Error", response = ErrorResponse.class ) }) public Response createBook(@Context UriInfo uriInfo, @ApiParam( value = "Book object you want to add", required = true ) @NotNull(message = "{requestBody.does.not.exist}") @Valid Book book) throws SQLException { LOGGER.debug("Inserting book {}", book); Book savedBook = bookService.add(book); URI createdUri = uriInfo.getRequestUriBuilder().path(savedBook.getId()).build(); return Response.created(createdUri).entity(savedBook).build(); }
@PUT @Consumes(MediaType.APPLICATION_JSON) @ApiOperation( value = "Update an existing book", response = Book.class ) @ApiResponses({ @ApiResponse( code = 200, message = "Book updated successfully" ), @ApiResponse( code = 400, message = "Bad request", response = ValidationError.class ), @ApiResponse( code = 401, message = "'Authorization' header is missing or wrong username/password", response = ErrorResponse.class, responseHeaders = @ResponseHeader( name = "WWW-Authenticate", description = "Defines the authentication method that should be used to gain access to a resource.", response = String.class ) ), @ApiResponse( code = 500, message = "Internal Server Error", response = ErrorResponse.class ) }) public Response updateBook(@NotNull(message = "{requestBody.does.not.exist}") @ApiParam( value = "Book object you want to update", required = true ) @ValidBookToUpdate @Valid Book book) throws SQLException { LOGGER.debug("Updating book {}", book); bookService.update(book); return Response.ok().build(); }
@Test public void testAddUserAsAdminButWithBadValues() { String email = null; String username = null; String[] roles = new String[]{"user"}; String hashedPassword = "password"; User user = buildUser(username, email, roles, hashedPassword); Entity<User> userEntity = Entity.entity(user, MediaType.APPLICATION_JSON_TYPE); Response response = target("users").request().header("Authorization", "Bearer " + AdminToken.getAuthToken()) .accept(MediaType.APPLICATION_JSON_TYPE).post(userEntity); List<ValidationError> validationErrorList = getValidationErrorList(response); assertEquals(400, response.getStatus()); assertNotNull(validationErrorList); // [ // { // "message": "may not be empty", // "messageTemplate": "{org.hibernate.validator.constraints.NotEmpty.message}", // "path": "UserResource.addUser.arg0.email", // "invalidValue": null // }, // { // "message": "may not be empty", // "messageTemplate": "{org.hibernate.validator.constraints.NotEmpty.message}", // "path": "UserResource.addUser.arg0.username", // "invalidValue": null // }, // { // "message": "Email can not be null", // "messageTemplate": "Email can not be null", // "path": "UserResource.addUser.arg0.email", // "invalidValue": null // }, // { // "message": "Username can not be null", // "messageTemplate": "Username can not be null", // "path": "UserResource.addUser.arg0.username", // "invalidValue": null // } // ] assertEquals(4, validationErrorList.size()); System.out.println("validationErrorList = " + validationErrorList); // assertEquals(email, responseUser.getEmail()); // assertEquals(username, responseUser.getUsername()); // assertArrayEquals(roles, responseUser.getRoles()); // assertEquals(hashedPassword, responseUser.getHashedPassword()); // assertNotNull(responseUser.getId()); }
private List<ValidationError> getValidationErrorList(final Response response) { return response.readEntity(new GenericType<List<ValidationError>>() { }); }
/** * Wrapper around {@link #contOnValidationError(Set[])} but instead of returning * a list of errors, this method will halt processing of the request by throwing * a BadRequestException, setting the HTTP status to 400 (BAD REQUEST) and providing * a full list of validation errors in the body of the response. * * Usage: * <pre> * Validator validator = getValidator(); * failOnValidationError( * validator.validateProperty(myObject, "uuid"), * validator.validateProperty(myObject, "name") * ); * // If validation fails, this line will not be reached. * </pre> * * @param violationsArray a Set of one or more ConstraintViolations * @since 1.0.0 */ @SafeVarargs protected final void failOnValidationError(final Set<ConstraintViolation<Object>>... violationsArray) { final List<ValidationError> errors = contOnValidationError(violationsArray); if (errors.size() > 0) { throw new BadRequestException(Response.status(Response.Status.BAD_REQUEST).entity(errors).build()); } }
/** * implement toResponse with code, message. * * @param e the validation exception object * @param code the code * @param message the message * * @return the response */ private Response toResponse(ConstraintViolationException e, int code, String message) { LOGGER.log(Level.FINER, LocalizationMessages.CONSTRAINT_VIOLATIONS_ENCOUNTERED(), e); List<ValidationError> errors = ValidationHelper.constraintViolationToValidationErrors(e); ParsecErrorResponse<ValidationError> errorResponse = ValidateUtil.buildErrorResponse(errors, code, message); return Response.status(Response.Status.BAD_REQUEST) .entity(new GenericEntity<ParsecErrorResponse<ValidationError>>(errorResponse) { }).build(); }
/** * Gets the detail. * * @return the detail */ public List<ValidationError> getDetail() { return detail; }
/** * Sets the detail. * * @param detail the detail to set */ public void setDetail(List<ValidationError> detail) { this.detail = detail; }