Class KiwiResources

java.lang.Object
org.kiwiproject.jaxrs.KiwiResources

public final class KiwiResources extends Object
Static utilities for use in Jakarta REST resource classes. Contains utilities for verifying entities (e.g. obtained from a service or data access class), factories for creating new responses, and for validating query parameters.
See Also:
API Note:
Some methods in this class accept Optional arguments, which we know is considered a code smell by various people and analysis tools such as IntelliJ's inspections, Sonar, etc. However, we also like to return Optional from data access code (e.g. a DAO "findById" method where the object might not exist if it was recently deleted). In such cases, we can simply take the Optional returned by those finder methods and pass them directly to the utilities provided here without needing to call additional methods, for example without needing to call orElse(null). So, we acknowledge that it is generally not good to accept Optional arguments, but we're trading off convenience in this class against "generally accepted" practice.
  • Method Summary

    Modifier and Type
    Method
    Description
    static jakarta.ws.rs.core.Response
    createdResponse(URI location, Object entity)
    Builds a Response with 201 Created status and a specified Location header and entity.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    createdResponseBuilder(URI location, Object entity)
    Creates a Response.ResponseBuilder having 201 Created status and a specified Location header and entity.
    static jakarta.ws.rs.core.Response
    newResponse(jakarta.ws.rs.core.Response.Status status, Object entity)
    Builds a Response having the given status and entity.
    static jakarta.ws.rs.core.Response
    newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, jakarta.ws.rs.core.MultivaluedMap<String,Object> headers)
    Builds a Response having the given status, entity, and headers.
    static jakarta.ws.rs.core.Response
    newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, String contentType)
    Builds a Response having the given status, entity, and content type.
    static jakarta.ws.rs.core.Response
    newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, Map<String,Object> singleValuedHeaders)
    Builds a Response having the given status, entity, and (single-valued) headers.
    static jakarta.ws.rs.core.Response
    newResponseBufferingEntityFrom(jakarta.ws.rs.core.Response originalResponse)
    Convenience wrapper around Response.fromResponse(Response) that also buffers the response entity by calling Response.bufferEntity() on the given response.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity)
    Creates a Response.ResponseBuilder having the given status and entity.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, jakarta.ws.rs.core.MultivaluedMap<String,Object> headers)
    Creates a Response.ResponseBuilder having the given status, entity, and headers.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, String contentType)
    Creates a Response.ResponseBuilder having the given status, entity, and content type.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, Map<String,Object> singleValuedHeaders)
    Creates a Response.ResponseBuilder having the given status, entity, and (single-valued) headers.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    newResponseBuilderBufferingEntityFrom(jakarta.ws.rs.core.Response originalResponse)
    Convenience wrapper around Response.fromResponse(Response) that also buffers the response entity by calling Response.bufferEntity() on the given response.
    static jakarta.ws.rs.core.Response
    Builds a Response with 200 OK status and a specified entity.
    static jakarta.ws.rs.core.Response.ResponseBuilder
    Creates a Response.ResponseBuilder having 200 OK status and a specified entity.
    static <V> int
    validateExactlyOneIntParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has exactly one value that can be converted into an integer.
    static <V> long
    validateExactlyOneLongParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has exactly one value that can be converted into a long.
    static <V> int
    validateIntParameter(Map<String,V> parameters, String parameterName)
    Checks whether parameters contains parameter named parameterName that is an integer or something that can be converted into an integer.
    static <V> long
    validateLongParameter(Map<String,V> parameters, String parameterName)
    Checks whether parameters contains parameter named parameterName that is a long or something that can be converted into a long.
    static <V> int
    validateOneIntParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into an integer.
    static <V> long
    validateOneLongParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into a long.
    static <V> List<Integer>
    validateOneOrMoreIntParameters(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into an integer.
    static <V> List<Long>
    validateOneOrMoreLongParameters(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
    Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into a long.
    static <T> @NonNull T
    verifyExistence(Optional<T> resourceEntity)
    Verifies that resourceEntity contains a value, otherwise throws a JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistence(Optional<T> resourceEntity, Class<T> entityType, Object identifier)
    Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistence(Optional<T> resourceEntity, String notFoundMessage)
    Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistence(Optional<T> resourceEntity, String notFoundMessageTemplate, Object... args)
    Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
    static <T> void
    verifyExistence(T resourceEntity)
    Verifies that resourceEntity is not null, otherwise throws a JaxrsNotFoundException.
    static <T> void
    verifyExistence(T resourceEntity, Class<T> entityType, Object identifier)
    Verifies that resourceEntity is not null, otherwise throws a JaxrsNotFoundException.
    static <T> void
    verifyExistence(T resourceEntity, String notFoundMessage)
    Verifies that resourceEntity is not null, otherwise throws JaxrsNotFoundException.
    static <T> void
    verifyExistence(T resourceEntity, String notFoundMessageTemplate, Object... args)
    Verifies that resourceEntity is not null, otherwise throws JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistenceAndReturn(T resourceEntity)
    Verifies that resourceEntity is not null and returns it, otherwise throws a JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistenceAndReturn(T resourceEntity, Class<T> entityType, Object identifier)
    Verifies that resourceEntity is not null and returns it, otherwise throws a JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistenceAndReturn(T resourceEntity, String notFoundMessage)
    Verifies that resourceEntity is not null and returns it, otherwise throws JaxrsNotFoundException.
    static <T> @NonNull T
    verifyExistenceAndReturn(T resourceEntity, String notFoundMessageTemplate, Object... args)
    Verifies that resourceEntity is not null and returns it, otherwise throws JaxrsNotFoundException.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • verifyExistence

      public static <T> void verifyExistence(T resourceEntity)
      Verifies that resourceEntity is not null, otherwise throws a JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistenceAndReturn

      public static <T> @NonNull T verifyExistenceAndReturn(T resourceEntity)
      Verifies that resourceEntity is not null and returns it, otherwise throws a JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      Returns:
      the entity, if it is not null
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistence

      public static <T> @NonNull T verifyExistence(Optional<T> resourceEntity)
      Verifies that resourceEntity contains a value, otherwise throws a JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      Returns:
      the entity if the Optional contains a value
      Throws:
      JaxrsNotFoundException - if the entity is empty
    • verifyExistence

      public static <T> void verifyExistence(T resourceEntity, Class<T> entityType, Object identifier)
      Verifies that resourceEntity is not null, otherwise throws a JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      entityType - a Class representing the entity type, used in error messages
      identifier - the unique identifier of the resource identity
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistenceAndReturn

      public static <T> @NonNull T verifyExistenceAndReturn(T resourceEntity, Class<T> entityType, Object identifier)
      Verifies that resourceEntity is not null and returns it, otherwise throws a JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      entityType - a Class representing the entity type, used in error messages
      identifier - the unique identifier of the resource identity
      Returns:
      the entity, if it is not null
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistence

      public static <T> @NonNull T verifyExistence(Optional<T> resourceEntity, Class<T> entityType, Object identifier)
      Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      entityType - a Class representing the entity type, used in error messages
      identifier - the unique identifier of the resource identity
      Returns:
      the entity if the Optional contains a value
      Throws:
      JaxrsNotFoundException - if the entity is empty
    • verifyExistence

      public static <T> void verifyExistence(T resourceEntity, String notFoundMessage)
      Verifies that resourceEntity is not null, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessage - the error message to include in the response entity
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistenceAndReturn

      public static <T> @NonNull T verifyExistenceAndReturn(T resourceEntity, String notFoundMessage)
      Verifies that resourceEntity is not null and returns it, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessage - the error message to include in the response entity
      Returns:
      the entity, if it is not null
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistence

      public static <T> @NonNull T verifyExistence(Optional<T> resourceEntity, String notFoundMessage)
      Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessage - the error message to include in the response entity
      Returns:
      the entity if the Optional contains a value
      Throws:
      JaxrsNotFoundException - if the entity is empty
    • verifyExistence

      public static <T> void verifyExistence(T resourceEntity, String notFoundMessageTemplate, Object... args)
      Verifies that resourceEntity is not null, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessageTemplate - template for the error message to include in the response entity; uses KiwiStrings.format to construct the message
      args - the arguments to be substituted into the message template
      Throws:
      JaxrsNotFoundException - if the entity is null
    • verifyExistenceAndReturn

      public static <T> @NonNull T verifyExistenceAndReturn(T resourceEntity, String notFoundMessageTemplate, Object... args)
      Verifies that resourceEntity is not null and returns it, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessageTemplate - template for the error message to include in the response entity; uses KiwiStrings.format to construct the message
      args - the arguments to be substituted into the message template
      Returns:
      the entity, if it is not null
      Throws:
      JaxrsNotFoundException - if the entity is empty
    • verifyExistence

      public static <T> @NonNull T verifyExistence(Optional<T> resourceEntity, String notFoundMessageTemplate, Object... args)
      Verifies that resourceEntity contains a value, otherwise throws JaxrsNotFoundException.
      Type Parameters:
      T - the object type
      Parameters:
      resourceEntity - the resource entity to verify
      notFoundMessageTemplate - template for the error message to include in the response entity; uses KiwiStrings.format to construct the message
      args - the arguments to be substituted into the message template
      Returns:
      the entity if the Optional contains a value
      Throws:
      JaxrsNotFoundException - if the entity is empty
    • newResponse

      public static jakarta.ws.rs.core.Response newResponse(jakarta.ws.rs.core.Response.Status status, Object entity)
      Builds a Response having the given status and entity.
      Parameters:
      status - the response status
      entity - the response entity
      Returns:
      a response
    • newResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity)
      Creates a Response.ResponseBuilder having the given status and entity. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      status - the response status
      entity - the response entity
      Returns:
      a response builder
    • newResponse

      public static jakarta.ws.rs.core.Response newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, String contentType)
      Builds a Response having the given status, entity, and content type.
      Parameters:
      status - the response status
      entity - the response entity
      contentType - the value for the Content-Type header
      Returns:
      a response
    • newResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, String contentType)
      Creates a Response.ResponseBuilder having the given status, entity, and content type. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      status - the response status
      entity - the response entity
      contentType - the value for the Content-Type header
      Returns:
      a response builder
    • newResponse

      public static jakarta.ws.rs.core.Response newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, Map<String,Object> singleValuedHeaders)
      Builds a Response having the given status, entity, and (single-valued) headers.
      Parameters:
      status - the response status
      entity - the response entity
      singleValuedHeaders - map containing single-valued response headers
      Returns:
      a response
    • newResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, Map<String,Object> singleValuedHeaders)
      Creates a Response.ResponseBuilder having the given status, entity, and (single-valued) headers. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      status - the response status
      entity - the response entity
      singleValuedHeaders - map containing single-valued response headers
      Returns:
      a response builder
    • newResponse

      public static jakarta.ws.rs.core.Response newResponse(jakarta.ws.rs.core.Response.Status status, Object entity, jakarta.ws.rs.core.MultivaluedMap<String,Object> headers)
      Builds a Response having the given status, entity, and headers.
      Parameters:
      status - the response status
      entity - the response entity
      headers - map containing response headers
      Returns:
      a response
    • newResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder newResponseBuilder(jakarta.ws.rs.core.Response.Status status, Object entity, jakarta.ws.rs.core.MultivaluedMap<String,Object> headers)
      Creates a Response.ResponseBuilder having the given status, entity, and headers. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      status - the response status
      entity - the response entity
      headers - map containing response headers
      Returns:
      a response builder
    • createdResponse

      public static jakarta.ws.rs.core.Response createdResponse(URI location, Object entity)
      Builds a Response with 201 Created status and a specified Location header and entity.
      Parameters:
      location - the value for the Location header
      entity - the response entity
      Returns:
      a 202 Created response
    • createdResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder createdResponseBuilder(URI location, Object entity)
      Creates a Response.ResponseBuilder having 201 Created status and a specified Location header and entity. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      location - the value for the Location header
      entity - the response entity
      Returns:
      a 201 Created response builder
    • okResponse

      public static jakarta.ws.rs.core.Response okResponse(Object entity)
      Builds a Response with 200 OK status and a specified entity.
      Parameters:
      entity - the response entity
      Returns:
      a 200 OK response
    • okResponseBuilder

      public static jakarta.ws.rs.core.Response.ResponseBuilder okResponseBuilder(Object entity)
      Creates a Response.ResponseBuilder having 200 OK status and a specified entity. You can further modify the returned build, e.g. add custom headers, set cookies. etc.
      Parameters:
      entity - the response entity
      Returns:
      a 200 OK response builder
    • newResponseBufferingEntityFrom

      public static jakarta.ws.rs.core.Response newResponseBufferingEntityFrom(jakarta.ws.rs.core.Response originalResponse)
      Convenience wrapper around Response.fromResponse(Response) that also buffers the response entity by calling Response.bufferEntity() on the given response. This returns a Response instead of a response builder.

      NOTE: The reason this method exists is due to the note in the Javadoc of Response.fromResponse(Response) which states: "Note that if the entity is backed by an un-consumed input stream, the reference to the stream is copied. In such case make sure to buffer the entity stream of the original response instance before passing it to this method." So, rather than having the same boilerplate code in various locations (or as we've seen many times, people forgetting to buffer the response entity), this provides a single method to perform the same logic and ensure the entity is buffered.

      Parameters:
      originalResponse - a Response from which the status code, entity and response headers will be copied.
      Returns:
      a new response
      See Also:
      • Response.fromResponse(Response)
      • Response.bufferEntity()
    • newResponseBuilderBufferingEntityFrom

      public static jakarta.ws.rs.core.Response.ResponseBuilder newResponseBuilderBufferingEntityFrom(jakarta.ws.rs.core.Response originalResponse)
      Convenience wrapper around Response.fromResponse(Response) that also buffers the response entity by calling Response.bufferEntity() on the given response.

      NOTE: The reason this method exists is due to the note in the Javadoc of Response.fromResponse(Response) which states: "Note that if the entity is backed by an un-consumed input stream, the reference to the stream is copied. In such case make sure to buffer the entity stream of the original response instance before passing it to this method." So, rather than having the same boilerplate code in various locations (or as we've seen many times, people forgetting to buffer the response entity), this provides a single method to perform the same logic and ensure the entity is buffered.

      Parameters:
      originalResponse - a Response from which the status code, entity and response headers will be copied.
      Returns:
      a new response builder
      See Also:
      • Response.fromResponse(Response)
      • Response.bufferEntity()
    • validateIntParameter

      public static <V> int validateIntParameter(Map<String,V> parameters, String parameterName)
      Checks whether parameters contains parameter named parameterName that is an integer or something that can be converted into an integer.
      Type Parameters:
      V - the type of values in the map
      Parameters:
      parameters - the parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the int value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present, or is not an integer
    • validateOneIntParameter

      public static <V> int validateOneIntParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into an integer. If there is more than one value, then the first one returned by MultivaluedMap.getFirst(Object) is returned.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the int value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with at least one value, or is not an integer
    • validateExactlyOneIntParameter

      public static <V> int validateExactlyOneIntParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has exactly one value that can be converted into an integer. If there is more than one value, this is considered a bad request and a JaxrsBadRequestException is thrown.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the int value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with only one value, or is not an integer
    • validateOneOrMoreIntParameters

      public static <V> List<Integer> validateOneOrMoreIntParameters(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into an integer. All the values must be convertible to integer, and they are all converted and returned in a List.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      an unmodifiable List containing the int values of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with at least one value, or is not an integer
    • validateLongParameter

      public static <V> long validateLongParameter(Map<String,V> parameters, String parameterName)
      Checks whether parameters contains parameter named parameterName that is a long or something that can be converted into a long.
      Type Parameters:
      V - the type of values in the map
      Parameters:
      parameters - the parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the long value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present, or is not a long
    • validateOneLongParameter

      public static <V> long validateOneLongParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into a long. If there is more than one value, then the first one returned by MultivaluedMap.getFirst(Object) is returned.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the long value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with at least one value, or is not a long
    • validateExactlyOneLongParameter

      public static <V> long validateExactlyOneLongParameter(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has exactly one value that can be converted into a long. If there is more than one value, this is considered a bad request and a JaxrsBadRequestException is thrown.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      the long value of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with at least one value, or is not a long
    • validateOneOrMoreLongParameters

      public static <V> List<Long> validateOneOrMoreLongParameters(jakarta.ws.rs.core.MultivaluedMap<String,V> parameters, String parameterName)
      Checks whether parameters contains a parameter named parameterName that has at least one value that can be converted into a long. All the values must be convertible to long, and they are all converted and returned in a List.
      Type Parameters:
      V - the type of values in the multivalued map
      Parameters:
      parameters - the multivalued parameters to check
      parameterName - name of the parameter which should be present
      Returns:
      an unmodifiable List containing the long values of the validated parameter
      Throws:
      JaxrsBadRequestException - if the specified parameter is not present with only one value, or is not a long