Results 1 to 6 of 6

Thread: Spring 3.0.1 Release Media Type issue - Spring Team

  1. #1

    Exclamation Spring 3.0.1 Release Media Type issue - Spring Team

    Hi

    I have begun using the Spring 3.0.1 maintainence release and have noticed an issue with the org.springframework.http.MediaType class.

    I had a bean definition of:

    Code:
    <bean id="htmlMediaType" class="org.springframework.http.MediaType">
        <constructor-arg value="text/html" />
    </bean>
    This bean was working successfully on Spring 3.0.0 Release but is now causing an issue. I am getting the following Exception:

    Code:
    Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.http.MediaType]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Invalid token character '/' in token "text/html"
    	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:107)
    	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:273)
    	... 39 more
    Caused by: java.lang.IllegalArgumentException: Invalid token character '/' in token "text/html"
    After looking at the code for the MediaType class however the check token method seems ok:

    Code:
    /**
    	 * Checks the given token string for illegal characters, as defined in RFC 2616, section 2.2.
    	 *
    	 * @throws IllegalArgumentException in case of illegal characters
    	 * @see <a href="http://tools.ietf.org/html/rfc2616#section-2.2">HTTP 1.1, section 2.2</a>
    	 */
    	private void checkToken(String s) {
    		for (int i=0; i < s.length(); i++ ) {
    			char ch = s.charAt(i);
    			if (!TOKEN.get(ch)) {
    				throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + s + "\"");
    			}
    		}
    	}
    The class defines the available seperators as:

    Code:
    BitSet separators = new BitSet(128);
    separators.set('(');
    separators.set(')');
    separators.set('<');
    separators.set('>');
    separators.set('@');
    separators.set(',');
    separators.set(';');
    separators.set(':');
    separators.set('\\');
    separators.set('\"');
    separators.set('/');
    separators.set('[');
    separators.set(']');
    separators.set('?');
    separators.set('=');
    separators.set('{');
    separators.set('}');
    separators.set(' ');
    separators.set('\t');
    The forward slash seems to be in there so I'm not too sure why this exception is now being thrown?

    Any ideas ??

    Eggsy

  2. #2

    Default AndNot

    Hi,

    Could it be because of the following line:

    Code:
    TOKEN.andNot(separators);
    Should this be:
    Code:
    TOKEN.add(seperators)?

  3. #3
    Join Date
    Jul 2005
    Location
    Rotterdam, the Netherlands
    Posts
    1,562

    Default

    Basically, the single-string constructor is there for constructing a media type with a '*' subtype. So in effect,

    Code:
    <bean id="htmlMediaType" class="org.springframework.http.MediaType">
        <constructor-arg value="text/html" />
    </bean>
    constructs a media type with type 'text/html' and subtype '*', which is probably not what you want. This behavior was also present in 3.0.0, we just didn't check for '/' before.

    What you want to use is the 2 string constructor, like so:
    Code:
    <bean id="htmlMediaType" class="org.springframework.http.MediaType">
        <constructor-arg value="text"/>
        <constructor-arg value="html"/>
    </bean>
    or use the parseMediaType factory method:
    Code:
    <bean id="htmlMediaType" class="org.springframework.http.MediaType" factoryMethod="parseMediaType">
        <constructor-arg value="text/html" />
    </bean>
    Also note that there is a MediaTypeEditor property editor present in Spring (which uses the parseMediaType method), so if you just want to inject a media type in another bean, you can just inject the string and Spring will do the conversion for you.
    Arjen Poutsma

    Spring Web Services Dev Lead
    Please read the FAQ

  4. #4

    Default Thanks

    Hi Arjen

    Oh right so was in fact it was actually an error in my code from the previous version.

    Thanks for the prompt response and description.

  5. #5
    Join Date
    Jun 2008
    Location
    Philadelphia, PA, USA
    Posts
    212

    Default

    FYI, thanks for this thread! In case anyone is reading this and attempting with Spring 3, you might get:

    Code:
    java.lang.IllegalArgumentException: Invalid token character '/' in token "text/html"
    	at org.springframework.http.MediaType.checkToken(MediaType.java:282)
    	at org.springframework.http.MediaType.<init>(MediaType.java:254)
    	at org.springframework.http.MediaType.<init>(MediaType.java:207)
    	at org.springframework.http.MediaType.<init>(MediaType.java:196)
    Use this other constructor instead:
    Code:
    <bean id="htmlMediaType" class="org.springframework.http.MediaType">
    		<constructor-arg value="text" />
    		<constructor-arg value="html" />
    	</bean>
    Referring to this thread post, thanks : http://forum.springsource.org/showthread.php?t=84464&highlight=tiles+content+neg otiation
    Ken Rimple
    Chariot Solutions
    email: krimple@chariotsolutions.com
    work: www.chariotsolutions.com/education
    personal: www.rimple.com

    Author: Spring Roo in Action (Manning)
    MEAP Site: manning.com/rimple

  6. #6
    Join Date
    Jun 2008
    Location
    Philadelphia, PA, USA
    Posts
    212

    Default

    One quick other note... I removed the "ignoreAcceptHeader" attribute and now code I'm using to experiment with REST works fine if you follow that mechanism too.

    So either using customers.xml as the URI, or using customers with the Accept: header set to application/json or application/xml, for example, works for me.

    Here's some Groovy code to use RESTClient to hack with a restful call...

    Code:
    @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0' )
    import groovyx.net.http.RESTClient
    import groovy.util.slurpersupport.GPathResult
    
    def customers = new RESTClient( 'http://localhost:8080/demo/')
    def results = customers.get (path : 'customers',
       headers: [Accept : 'application/xml', "Accept-Encoding" : 'gzip,deflate'])
    
    println results.data
    
    // if this were XML you could do:
    results.data.customer.each { c ->
      println "customer:  $c.id, $c.firstname $c.lastname"
    }
    
    // and you can set the Accept header to 'application/json', etc...
    Ken Rimple
    Chariot Solutions
    email: krimple@chariotsolutions.com
    work: www.chariotsolutions.com/education
    personal: www.rimple.com

    Author: Spring Roo in Action (Manning)
    MEAP Site: manning.com/rimple

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •