jms-spec
  1. jms-spec
  2. JMS_SPEC-101

New methods Message.getBody(Class<T> c) and isBodyAssignableTo(Class c)

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.1
    • Fix Version/s: 2.0PD, 2.0
    • Labels:
      None

      Description

      This is a proposal to add a new method to javax.jms.Message which allows the message payload to be obtained without the need to cast the object to the appropriate subtype first. This can slightly simplify the code of a MessageListener's, onMessage method, where the object passed in is always declared to be a javax.jms.Message.

      Here is the proposed API:

      	/**
      	 * Returns the messages's payload, which must be of the specified type. If
      	 * the message has no payload then null is returned. This method may be used
      	 * to obtain the payload of any type of message except for
      	 * <tt>StreamMessage</tt>.
      	 * 
      	 * @param c
      	 *            The class of the payload.<br/>
      	 *            If the message is a <code>TextMessage</code> then this should
      	 *            be set to <code>String.class</code>.<br/>
      	 *            If the message is a <code>ObjectMessage</code> then this
      	 *            should be set to <code>java.io.Serializable.class</code>. <br/>
      	 *            If the message is a <code>MapMessage</code> then this should
      	 *            be set to <code>java.util.Map.class</code>.<br/>
      	 *            If the message is a <code>BytesMessage</code> then this should
      	 *            be set to <code>byte[].class</code>.<br/>
      	 *            If the message payload is not of the specified type a
      	 *            <code>MessageFormatException</code> will be thrown
      	 * 
      	 * @return the messages's payload
      	 * 
      	 * @exception JMSException
      	 *                if the JMS provider fails to get the payload due to some
      	 *                internal error.
      	 * @exception MessageFormatException
      	 *                if the payload is not of the specified type or, if the
      	 *                message is an ObjectMessage, if object deserialization
      	 *                fails.
      	 * @Exception MessageNotReadableException - if the message is a BytesMessage
      	 *                and the message is in write-only mode.
      	 */
      	<T> T getPayload(Class<T> c) throws JMSException;
      

      This means that instead of something like:

          public void onMessage(Message message) {
              String payload = ((TextMessage) message).getText();
      

      we could have

          public void onMessage(Message message) {
              String payload2 = message.getPayload(String.class); 
      

        Issue Links

          Activity

          Hide
          Nigel Deakin added a comment -

          Here's an updated proposal:

          	/**
          	 * Returns the messages's payload, which must be assignable to the specified
          	 * type. If the message has no payload then null is returned. This method
          	 * may be used to obtain the payload of any type of message except for
          	 * <tt>StreamMessage</tt>.
          	 * 
          	 * @param c
          	 *            The class of the payload.
          	 *            <br/>
          	 *            If the message is a <code>TextMessage</code> then this should
          	 *            be set to <code>String.class</code> or any other class to
          	 *            which a String is assignable.
          	 *            <br/>
          	 *            If the message is a <code>ObjectMessage</code> then this
          	 *            should be set to <code>java.io.Serializable.class</code> or
          	 *            any other class to which the payload is assignable.
          	 *            <br/>
          	 *            If the message is a <code>MapMessage</code> then this should
          	 *            be set to <code>java.util.Map.class</code>.
          	 *            <br/>
          	 *            If the message is a <code>BytesMessage</code> then this should
          	 *            be set to <code>byte[].class</code>.
          	 * 
          	 * @return the messages's payload
          	 * 
          	 * @exception JMSException
          	 *                if the JMS provider fails to get the payload due to some
          	 *                internal error.
          	 * @exception MessageFormatException
          	 *                if the message is a <code>StreamMessage</code>, or the
          	 *                payload cannot be assigned to the specified type, or the
          	 *                message is an <code>ObjectMessage</code> and object deserialization
          	 *                fails.
          	 * @exception MessageNotReadableException - if the message is a <code>BytesMessage</code>
          	 *                and the message is in write-only mode.
          	 */
          	<T> T getPayload(Class<T> c) throws JMSException;
          
          Show
          Nigel Deakin added a comment - Here's an updated proposal: /** * Returns the messages's payload, which must be assignable to the specified * type. If the message has no payload then null is returned. This method * may be used to obtain the payload of any type of message except for * <tt>StreamMessage</tt>. * * @param c * The class of the payload. * <br/> * If the message is a <code>TextMessage</code> then this should * be set to <code>String.class</code> or any other class to * which a String is assignable. * <br/> * If the message is a <code>ObjectMessage</code> then this * should be set to <code>java.io.Serializable.class</code> or * any other class to which the payload is assignable. * <br/> * If the message is a <code>MapMessage</code> then this should * be set to <code>java.util.Map.class</code>. * <br/> * If the message is a <code>BytesMessage</code> then this should * be set to <code>byte[].class</code>. * * @return the messages's payload * * @exception JMSException * if the JMS provider fails to get the payload due to some * internal error. * @exception MessageFormatException * if the message is a <code>StreamMessage</code>, or the * payload cannot be assigned to the specified type, or the * message is an <code>ObjectMessage</code> and object deserialization * fails. * @exception MessageNotReadableException - if the message is a <code>BytesMessage</code> * and the message is in write-only mode. */ <T> T getPayload(Class<T> c) throws JMSException;
          Hide
          Nigel Deakin added a comment -

          Following discussion on the expert group the name of this proposed method is changed from getPayload to getBody (for consistency with established JMS 1.1 terminology). Minor changes have also been made to the wording. Here's the latest draft API:

          	/**
          	 * Returns the message body as an object of the specified type. The message
          	 * body must be capable of being assigned to the specified type. This means
          	 * that the specified class or interface must be either the same as, or a
          	 * superclass or superinterface of, the class of the message body. This
          	 * method may be used to obtain the body of any type of message except for
          	 * <tt>StreamMessage</tt>. If the message has no body then null is returned.
          	 * 
          	 * @param c
          	 *            The type to which the message body should be assigned. <br/>
          	 *            If the message is a <code>TextMessage</code> then this should
          	 *            be set to <code>String.class</code> or another class to which
          	 *            a String is assignable. <br/>
          	 *            If the message is a <code>ObjectMessage</code> then this
          	 *            should be set to <code>java.io.Serializable.class</code> or
          	 *            another class to which the payload is assignable. <br/>
          	 *            If the message is a <code>MapMessage</code> then this should
          	 *            be set to <code>java.util.Map.class</code>. <br/>
          	 *            If the message is a <code>BytesMessage</code> then this should
          	 *            be set to <code>byte[].class</code>. The
          	 *            <code>BytesMessage</code> must not be in write-only mode.
          	 * 
          	 * @return the message body
          	 * 
          	 * @exception JMSException
          	 *                if the JMS provider fails to get the message body due to
          	 *                some internal error.
          	 * @exception MessageFormatException
          	 *                if the message is a <code>StreamMessage</code>, or the
          	 *                message body cannot be assigned to the specified type, or
          	 *                the message is an <code>ObjectMessage</code> and object
          	 *                deserialization fails.
          	 * @exception MessageNotReadableException
          	 *                if the message is a <code>BytesMessage</code> and the
          	 *                message is in write-only mode.
          	 */
          	<T> T getBody(Class<T> c) throws JMSException;
          

          In addition, there has been a proposal to provide an additional method isBodyAssignableTo which can be used to find out whether a subsequent call to getBody would throw a MessageFormatException. Here it is:

          	/**
          	 * Returns whether the message body is capable of being assigned to the
          	 * specified type. If this method returns true then a subsequent call to the
          	 * method <code>getBody</code> with the same type argument would not throw a
          	 * MessageFormatException.
          	 * <p>
          	 * If the message is a <code>StreamMessage</code> then false is returned. If
          	 * the message is a <code>ObjectMessage</code> and object deserialization
          	 * fails then false is returned. If the message has no body then true is
          	 * returned.
          	 * 
          	 * @param c
          	 *            The specified type <br/>
          	 *            If the message is a <code>TextMessage</code> then method will
          	 *            only return true if this parameter is set to
          	 *            <code>String.class</code> or another class to which a String
          	 *            is assignable. <br/>
          	 *            If the message is a <code>ObjectMessage</code> then this
          	 *            method will only return true if this parameter is set to
          	 *            <code>java.io.Serializable.class</code> or another class to
          	 *            which the payload is assignable. <br/>
          	 *            If the message is a <code>MapMessage</code> then this method
          	 *            will only return true if this parameter is set to
          	 *            <code>java.util.Map.class</code>. <br/>
          	 *            If the message is a <code>BytesMessage</code> then this this
          	 *            method will only return true if this parameter is set to
          	 *            <code>byte[].class</code>.
          	 * 
          	 * @return whether the message body is capable of being assigned to the
          	 *         specified type
          	 * 
          	 * @exception JMSException
          	 *                if the JMS provider fails to return a value due to some
          	 *                internal error.
          	 * @exception MessageNotReadableException
          	 *                if the message is a <code>BytesMessage</code> and the
          	 *                message is in write-only mode.
          	 */
          	boolean isBodyAssignableTo(Class c) throws JMSException;
          
          Show
          Nigel Deakin added a comment - Following discussion on the expert group the name of this proposed method is changed from getPayload to getBody (for consistency with established JMS 1.1 terminology). Minor changes have also been made to the wording. Here's the latest draft API: /** * Returns the message body as an object of the specified type. The message * body must be capable of being assigned to the specified type. This means * that the specified class or interface must be either the same as, or a * superclass or superinterface of, the class of the message body. This * method may be used to obtain the body of any type of message except for * <tt>StreamMessage</tt>. If the message has no body then null is returned. * * @param c * The type to which the message body should be assigned. <br/> * If the message is a <code>TextMessage</code> then this should * be set to <code>String.class</code> or another class to which * a String is assignable. <br/> * If the message is a <code>ObjectMessage</code> then this * should be set to <code>java.io.Serializable.class</code> or * another class to which the payload is assignable. <br/> * If the message is a <code>MapMessage</code> then this should * be set to <code>java.util.Map.class</code>. <br/> * If the message is a <code>BytesMessage</code> then this should * be set to <code>byte[].class</code>. The * <code>BytesMessage</code> must not be in write-only mode. * * @return the message body * * @exception JMSException * if the JMS provider fails to get the message body due to * some internal error. * @exception MessageFormatException * if the message is a <code>StreamMessage</code>, or the * message body cannot be assigned to the specified type, or * the message is an <code>ObjectMessage</code> and object * deserialization fails. * @exception MessageNotReadableException * if the message is a <code>BytesMessage</code> and the * message is in write-only mode. */ <T> T getBody(Class<T> c) throws JMSException; In addition, there has been a proposal to provide an additional method isBodyAssignableTo which can be used to find out whether a subsequent call to getBody would throw a MessageFormatException. Here it is: /** * Returns whether the message body is capable of being assigned to the * specified type. If this method returns true then a subsequent call to the * method <code>getBody</code> with the same type argument would not throw a * MessageFormatException. * <p> * If the message is a <code>StreamMessage</code> then false is returned. If * the message is a <code>ObjectMessage</code> and object deserialization * fails then false is returned. If the message has no body then true is * returned. * * @param c * The specified type <br/> * If the message is a <code>TextMessage</code> then method will * only return true if this parameter is set to * <code>String.class</code> or another class to which a String * is assignable. <br/> * If the message is a <code>ObjectMessage</code> then this * method will only return true if this parameter is set to * <code>java.io.Serializable.class</code> or another class to * which the payload is assignable. <br/> * If the message is a <code>MapMessage</code> then this method * will only return true if this parameter is set to * <code>java.util.Map.class</code>. <br/> * If the message is a <code>BytesMessage</code> then this this * method will only return true if this parameter is set to * <code>byte[].class</code>. * * @return whether the message body is capable of being assigned to the * specified type * * @exception JMSException * if the JMS provider fails to return a value due to some * internal error. * @exception MessageNotReadableException * if the message is a <code>BytesMessage</code> and the * message is in write-only mode. */ boolean isBodyAssignableTo(Class c) throws JMSException;
          Hide
          Nigel Deakin added a comment -

          Change issue summary to refer to getBody instead of getPayload.

          Show
          Nigel Deakin added a comment - Change issue summary to refer to getBody instead of getPayload .
          Hide
          Nigel Deakin added a comment -

          This is now approved and added to the public draft.

          Show
          Nigel Deakin added a comment - This is now approved and added to the public draft.

            People

            • Assignee:
              Unassigned
              Reporter:
              Nigel Deakin
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: