Spring-Android: Spring for Android!!!

With an aim to ease the development of android applications Spring-Android, an extension to Spring framework is released.The framework with it's first release brings in RestTemplate and commons-logging support for the Android based applications.

This blog is the result of my experience while using the Spring-Android framework in one of the android applications that I am currently working on.This post mainly focuses on the steps involved to get it working.

The sample Webservice in this scenario has a method defined to handle GET requests that return all the Projects presently configured along with certain details and an array of issues. The class is as below:

  

public class Project {
    privateString name;
    privateInteger id;
    privateString owner;
    privateIssue[] issues;
    …
    //getter and setters for all
    …
}


On a Web-service GET request, the project data is retrieved in JSON representation.
A request to get all projects configured in the system gets back with the response below:

[{"class":"com.xyz.Project","id":1,"issues":[],"name":"TestProject0","owner":"Test0"},
{"class":"com.xyz.Project","id":2,"issues":[],"name":"TestProject1","owner":"Test1"},
{"class":"com.xyz.Project","id":3,"issues":[],"name":"TestProject2","owner":"Test2"}]


That completes the Rest service scenario description. Now let's find out how to access it in an Android application using Spring-Android's RestTemplate.

With my basic eclipse Android project already in place, I just created a lib folder so as to include Spring-Android's jar. You can download the jar files fromhere

Specifically, I have included spring-android-rest-template-1.0.0.M1.jar and spring-android-commons-logging-1.0.0.M1.jar.
Apart from these two, we need to have commons-httpclient 3.x jar. This jar is required for using Spring-Android's RestTemplate. Android supports commons-httpclient 4.x. and Spring-Android's RestTemplate may support this in future.

Please note that we have to include the Jars from the lib folder to the Project's class path for the Dex compilation process.

Now, with the basic setup done, let's move over to our simple Android Activity that makes use of the Spring-Android's RestTemplate.

public class DefaultActivity extendsActivity {
    /** Called when the activity is first created. */
    @Override
    publicvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
    RestTemplate restTemplate =new RestTemplate();
    restTemplate.setRequestFactory(newCommonsClientHttpRequestFactory());
    String url ="http://192.168.1.146:8080/grailsRestWS/project/";
    String data = restTemplate.getForObject(url, String.class);
    setContentView(R.layout.main);
    }


Let's try to understand the code given above

Line 7: It creates a restTemplate object. The RestTemplate aides Restful communication with the HTTP servers.

Line 8: The restTemplate is assigned a requestFactory.
RequestFactory is used for creating HttpClientRequest representing a client side http request.

Line 9: The url used is not localhost or the loop back address 127.0.0.1.
You might have guessed it already. The application is deployed onto a device or an Android emulator. It is the device that takes the localhost IP not the development machine. To resolve this, I have used the IP address as per my machine's network configuration.

Line 10: It is a rest call to the web-service url. Please notice that it is a HTTP GET request as indicated by the name getForObject().
I have specified the String.class as the second argument to the method which means the data returned is to be interpreted as String data.

The method supported by the RestTemplate are listed below

HTTP            RestTemplate
DELETE          delete(String, String...)
GET             getForObject(String, Class, String...)
HEAD            headForHeaders(String, String...)
OPTIONS         optionsForAllow(String, String...)
POST            postForLocation(String, Object, String...)
PUT             put(String, Object, String...)

But, when I try to run this code I get an exception

no suitable HttpMessageConverter found for response type [com.xebia.android.Project] and
content type [application/json]

That's because we are not dealing with text data here but JSON data type

Making this work requires few changes to our activity class. Below are the changes to be made

public class DefaultActivity extendsActivity {
    /** Called when the activity is first created. */
    @Override
    publicvoid onCreate(Bundle savedInstanceState) {
        ...
        RestTemplate restTemplate = <strong>getRestTemplate()</strong>;
        JSONData[] jsonData =   restTemplate.getForObject(url,ProjectData[].class);
        ...
    }
 
    privateRestTemplate getRestTemplate() {
        RestTemplate restTemplate =new RestTemplate();
        restTemplate.setRequestFactory(newCommonsClientHttpRequestFactory());
        <strong>MappingJacksonHttpMessageConverter jsonConverter =
                                newMappingJacksonHttpMessageConverter();
        List<MediaType> supportedMediaTypes =new ArrayList<MediaType>();
        supportedMediaTypes.add(newMediaType("application","json"));
        jsonConverter.setSupportedMediaTypes(supportedMediaTypes);</strong>
 
        List<HttpMessageConverter<?>> listHttpMessageConverters = restTemplate
                .getMessageConverters();
        restTemplate.setMessageConverters(listHttpMessageConverters);
        returnrestTemplate;
    }


To handle the JSON array data the response should be understandable by the restTemplate.

As such, in the code above I have registered a MappingJacksonHttpMessageConverterwith the restTemplate so as to read and write JSON data.

Also, we need to convey what sort of data our converter can handle e.g. text, xml, jpeg, json etc.
This is done by defining a supported MediaType which in our case is MediaType("application","json")

You may have noticed that the second argument to the getForObject method in the code above is changed from String.class to ProjectData.class.
This is because the messageCoverters for JSON and the mediaType which our converter can handle have been implemented.
We can now safely state that the response from the web service is an array of ProjectData.

Here's our Android client side class representing Project data

@JsonIgnoreProperties( {"class"})
public class JSONData {
    privateString name;
    privateInteger id;
    privateString owner;
    privateIssue[] issues;
    …
    //getter and setters for all
    …
}


here, JsonIgnoreProperties annotation conveys the JSON mapper that these are the properties to be excluded.
The JSON response contains a class variable which I am ignoring in the code above.

{"class":"com.xyz.Project","id":1,"issues":[],"name":"TestProject0","owner":"Test0"}

Please note that issues property is declared as an array. This is because with JSON it's easier to work with arrays.

Note: I was getting java.lang.VerifyError when I tried to run the application in my environment and after including jackson-core-asl-1.6.1.jar and jackson-mapper-asl-1.6.1.jar everything seems to be working fine.

The post just describes RestFul GET method using Spring-Android's RestTemplate.The other supported RestFul methods can also be implemented in similar manner. This is the first milestone release for Spring-Android and much more can be expected in the future releases-Spring Security OAuth client being one of them.


Reference: http://xebee.xebia.in/2010/12/31/spring-android-spring-for-android/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值