On my current project, the server has to have the ability to receive image data embedded in a JSON object, therefore the JSON string representing the data is a base64 encoding of the binary image. The entity model (that is persisted to the DB through JPA/Hibernate) has the image data field of type byte[].
Turns out that JBoss' RESTEasy is smart enough to use Jackson's ability to decode base64 text based on the type of the destination field.
That intuitive step by the framework is what helps give me a good feeling inside knowing I don't have to deal with type conversions, just what I want to do with the data.
Next task off the board please ....
Friday, April 15, 2011
Monday, March 28, 2011
FF obeys the rules and Spring 3 chokes
It's really quite sad/annoying when a toolkit as sophisticated as Spring chokes on simple matters.
I'm writing a GWT client to make RPC (XML/HTTP) calls to the server which is implemented in Spring MVC. My Controller has a @RequestBody on the input type which is a class that is annotated with JAXB annotations to serialise/deserialise from XML. Therefore my Controller is at the mercy of the HttpMessageConverter that Spring uses to rip the data out of the HTTP request, turn it into a POJO and give it to my Controller.
In the Spring config (I use the XML config), the <mvc:annotation-driven/> by default registers an instance of AnnotationMethodHandlerAdapter which (among other duties) is responsible for determining which message converter to use. What is nice is that a JAXB converter is registered automatically if the JAXB libs are on the classpath. The converter that is chosen is the one that can process the MIME type or Content-Type that is in the HTTP request header. In this case it would be application/xml which is processed by the default MarshallingHttpMessageConverter which in turn delegates the real work to JAXB.
However Firefox (FF) obeys the rules regarding XHR requests, in that it appends to the Content-Type header a charset. So application/xml becomes application/xml; charset=UTF-8. Because of this the entire server side code unravels because the Content-Type is not smart enough to parse the charset out of the Content-Type header; and throws an exception that the Content-Type is not recognised.
The solution after much reading up on the internals of the Spring MVC framework is to create my own bean tree where the supported type contains the charset. The message converters support changing the supported MIME types, which are modelled by the class MediaType. MediaType supports a Charset in its constructor. Therefore I end up with the following config.
Given the framework for converting data from HTTP requests already contains the logic to parse out Content-Type from the header, it's a shame that the default beans that are created by the <mvc:annotation-driven/> don't parse the charset properly instead of throwing an exception, given that it is part of the standard to include a charset in XHR requests. All XML/HTTP requests wont be XHR requests it's true, but given the prevalence of AJAX apps out there; the framework should account for it.
References
Spring 3 API
I'm writing a GWT client to make RPC (XML/HTTP) calls to the server which is implemented in Spring MVC. My Controller has a @RequestBody on the input type which is a class that is annotated with JAXB annotations to serialise/deserialise from XML. Therefore my Controller is at the mercy of the HttpMessageConverter that Spring uses to rip the data out of the HTTP request, turn it into a POJO and give it to my Controller.
In the Spring config (I use the XML config), the <mvc:annotation-driven/> by default registers an instance of AnnotationMethodHandlerAdapter which (among other duties) is responsible for determining which message converter to use. What is nice is that a JAXB converter is registered automatically if the JAXB libs are on the classpath. The converter that is chosen is the one that can process the MIME type or Content-Type that is in the HTTP request header. In this case it would be application/xml which is processed by the default MarshallingHttpMessageConverter which in turn delegates the real work to JAXB.
However Firefox (FF) obeys the rules regarding XHR requests, in that it appends to the Content-Type header a charset. So application/xml becomes application/xml; charset=UTF-8. Because of this the entire server side code unravels because the Content-Type is not smart enough to parse the charset out of the Content-Type header; and throws an exception that the Content-Type is not recognised.
The solution after much reading up on the internals of the Spring MVC framework is to create my own bean tree where the supported type contains the charset. The message converters support changing the supported MIME types, which are modelled by the class MediaType. MediaType supports a Charset in its constructor. Therefore I end up with the following config.
<!-- Override default AnnotationMethodHandlerAdapter that
mvc:annotation-driven provides -->
<bean class="org.springframework.web.servlet.mvc.
annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringHttpMessageConverter" />
<ref bean="marshallingHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.
MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxbMarshaller" />
<property name="unmarshaller" ref="jaxbMarshaller" />
<property name="supportedMediaTypes">
<list>
<!-- This handles browsers like FF who add
the charset to the XHR request. -->
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="application"/>
<constructor-arg index="1" value="xml"/>
<constructor-arg index="2" value="UTF-8"/>
</bean>
</list>
</property>
</bean>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.
StringHttpMessageConverter"/>
<oxm:jaxb2-marshaller id="jaxbMarshaller"
contextPath="org.altaregomelb.sync.domain"/>
Given the framework for converting data from HTTP requests already contains the logic to parse out Content-Type from the header, it's a shame that the default beans that are created by the <mvc:annotation-driven/> don't parse the charset properly instead of throwing an exception, given that it is part of the standard to include a charset in XHR requests. All XML/HTTP requests wont be XHR requests it's true, but given the prevalence of AJAX apps out there; the framework should account for it.
References
Spring 3 API
Thursday, February 24, 2011
Technological justice
In The Age today, it's reported that the Federal court backed iiNet. Finally some sane and reasonable justice from the courts in technological matters.
Well done iiNet.
Well done iiNet.
Wednesday, February 2, 2011
How to prepopulate your GAE dev_server for testing
This post assumes that you know how the Google App Engine Datastore basically works, and how to perform local unit testing of your code on the dev_server provided in the GAE SDK.
There is a massive gaping hole in the GAE SDK, both in terms of functionality and documentation (of course if there is some documentation on the matter please post it in the comments) in regards to the population of your local datastore (which is persisted to a file) for testing. Why does this matter? For integration, or acceptance testing. Not all testing my Google Overlords wants to be done in a memory only datastore, or within the one process/JVM/however Eclipse runs my dev_server and my JUnit tests.
Even if you setup your test code to point to the same file that your dev_server is reading from, your application wont see your entities. To say it's a frustrating problem is an understatement. Turns out there is a combination of fields that have to be set in your test code for the underlying datastore code to populate the file in such a way to get this to work
Rather than repeat the solution, it can be on the ever helpful Stack Overflow
This solution was found though a lot of pain, trial and error. I hope someone gets a use out of this post to prevent them agonising over the amount of blood lost from when their head hit the desk screaming "why Google why!!!!"
There is a massive gaping hole in the GAE SDK, both in terms of functionality and documentation (of course if there is some documentation on the matter please post it in the comments) in regards to the population of your local datastore (which is persisted to a file) for testing. Why does this matter? For integration, or acceptance testing. Not all testing my Google Overlords wants to be done in a memory only datastore, or within the one process/JVM/however Eclipse runs my dev_server and my JUnit tests.
Even if you setup your test code to point to the same file that your dev_server is reading from, your application wont see your entities. To say it's a frustrating problem is an understatement. Turns out there is a combination of fields that have to be set in your test code for the underlying datastore code to populate the file in such a way to get this to work
Rather than repeat the solution, it can be on the ever helpful Stack Overflow
This solution was found though a lot of pain, trial and error. I hope someone gets a use out of this post to prevent them agonising over the amount of blood lost from when their head hit the desk screaming "why Google why!!!!"
Friday, January 21, 2011
How to beat the competition by being more agile
Over at Forbes there's a discussion about how Facebook beat MySpace. The simple solution I got out of that was Facebook is more agile, but that they also priotise customer input. Enough users want something, Facebook gives it to them (and one would assume as fast as possible). That's responding to change, obviously a key Agile principle.
Makes me think about how doing business might continue to change over the years. The suits and the bean counters may want to do one thing (lots of Powerpoint presos with forecasts), and the techs on the ground might only be thinking three months ahead - getting the latest feature out the door. There's something to be said for long term vision but do short term sprints take precedence? After all the company has to make money to keep the suits in a job.
One thing Facebook does need to do is focus on quality. To much of it breaks (and often non deterministically). The fact that I can't invite friends to an event now for three days means something's going dreadfully wrong. Since you listen to customers Facebook, can you please fix your defective parts as well as push out the latest and greatest features?
Makes me think about how doing business might continue to change over the years. The suits and the bean counters may want to do one thing (lots of Powerpoint presos with forecasts), and the techs on the ground might only be thinking three months ahead - getting the latest feature out the door. There's something to be said for long term vision but do short term sprints take precedence? After all the company has to make money to keep the suits in a job.
One thing Facebook does need to do is focus on quality. To much of it breaks (and often non deterministically). The fact that I can't invite friends to an event now for three days means something's going dreadfully wrong. Since you listen to customers Facebook, can you please fix your defective parts as well as push out the latest and greatest features?
Wednesday, December 22, 2010
Holidaying with Android Froyo
Over the Christmas break, my wife wants to do some traveling. Which is all good and well, except that I have some coding that I want to. I'm sure that a lot people experience this problem.
My biggest annoyance was the lack of internet to look up API docs/reference material on the road for some tech that I want to dabble with. So I considered getting a 3G wireless modem.
Last week, my HTC Magic got upgraded to Froyo (2.2.1 actually), which of course comes with the ability to tether via USB to my computer. A quick google found instructions on how to enable the tethering on Gentoo Linux. A quick kernel config and module compile; followed by some bash scripting to modprobe cdc_ether, rndis_host and usbnet - and I had a usb0 interface sitting next to my eth0 interface. DHCP takes care of getting an IP address from the phone and I'm connected. If you're a Gentoo user, you should symlink /etc/init.d/net.lo to /etc/init.d/net.usb0 like net.eth0 for a convenient startup/shutdown script. One of the best bits is that the phone charges off the USB as well so I'm not draining the battery.
I even used my tethered connection to load Vodafone's coverage map for where we're going to show to my wife. Though knowing Vodafone the best laid USB tethering plans of mice and men are oft to go awry
My biggest annoyance was the lack of internet to look up API docs/reference material on the road for some tech that I want to dabble with. So I considered getting a 3G wireless modem.
Last week, my HTC Magic got upgraded to Froyo (2.2.1 actually), which of course comes with the ability to tether via USB to my computer. A quick google found instructions on how to enable the tethering on Gentoo Linux. A quick kernel config and module compile; followed by some bash scripting to modprobe cdc_ether, rndis_host and usbnet - and I had a usb0 interface sitting next to my eth0 interface. DHCP takes care of getting an IP address from the phone and I'm connected. If you're a Gentoo user, you should symlink /etc/init.d/net.lo to /etc/init.d/net.usb0 like net.eth0 for a convenient startup/shutdown script. One of the best bits is that the phone charges off the USB as well so I'm not draining the battery.
I even used my tethered connection to load Vodafone's coverage map for where we're going to show to my wife. Though knowing Vodafone the best laid USB tethering plans of mice and men are oft to go awry
Subscribe to:
Posts (Atom)