Chinaunix首页 | 论坛 | 博客
  • 博客访问: 369649
  • 博文数量: 100
  • 博客积分: 2586
  • 博客等级: 少校
  • 技术积分: 829
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-09 15:20
个人简介

我是一个Java爱好者

文章分类

全部博文(100)

文章存档

2014年(2)

2013年(7)

2012年(2)

2010年(44)

2009年(28)

2008年(17)

我的朋友

分类: Java

2014-08-11 17:02:21

In an earlier post we saw how to work create REST services using Spring. For testing the same we used a RESTClient Plugin available with Firefox.
It is often the case that we need our test code to be in Java so that it can be reused by others too. Spring provides us with an easy to use Rest Service client that can be used in our code.
The first step would be to configure our client:

From the code docs:

The central class for client-side HTTP access. It simplifies
communication with HTTP servers, and enforces RESTful principles.
It handles HTTP connections, leaving application code to provide
URLs (with possible template variables) and extract results.

True to its docs, the class does wrap lot of the code related to HTTP and allows us to focus on the operations exposed by the REST API. I first decided to test the retrieve record methods of the user resource:

@Component(value = "userRestClient")
public class UserRestClient {

   @Autowired
   private RestTemplate restTemplate;

   private final static String userServiceUrl = "";

   public User getUser(final int id) {
      return this.restTemplate.getForObject(userServiceUrl + "{id}",
            User.class, id);
   }

   public static void main(final String[] args) {
      final ApplicationContext appContext = new ClassPathXmlApplicationContext(
            "client.xml");
      final UserRestClient restClient = (UserRestClient) appContext
            .getBean("userRestClient");
      final User user = restClient.getUser(1);
      System.out.println(user.getName() + " is of age " + user.getAge());
   }
}

The method uses the getForObject call to retrieve a User record. The URL as we saw earlier needs the id to be placed at the end. The restClient allows us to use the parametrized URL, taking care of generating the actual URL and making the call. The object returned is of type as specified by the class parameter. The third parameter is a var-args method that is used to specify the values to replace in the URL. The log indicates a successful run:

2013-06-15 17:31:33 DEBUG RestTemplate:78 - Created GET request for "
lhost:8080/SampleRest/api/user/1"
2013-06-15 17:31:33 DEBUG RestTemplate:528 - Setting request Accept header to [a
pplication/json]
2013-06-15 17:31:33 DEBUG RestTemplate:473 - GET request for "
080/SampleRest/api/user/1" resulted in 200 (OK)
2013-06-15 17:31:33 DEBUG RestTemplate:78 - Reading [com.test.controller.User] a
s "application/json;charset=UTF-8" using [org.springframework.http.converter.jso
]
William is of age 12

In the above method we directly got access to the User object. However it could often be the case that we need to access the response headers. Or check if the response returned expected Status.
For this we have the ResponseEntity.

public User getUser(final String name) {
      final HashMap urlVariables = new HashMap(
            1);
      urlVariables.put("name", name);
      final String urlTemplate = userServiceUrl + "search/{name}";
      final ResponseEntity responseEntity = this.restTemplate
            .getForEntity(urlTemplate, User.class, urlVariables);

      System.out.println("Response Status : " + responseEntity.getStatusCode());

      final HttpHeaders headers = responseEntity.getHeaders();
      System.out.println("headers in response are : " + headers);
      return responseEntity.getBody();
   }

I tested the same:

      User user = restClient.getUser("William");
      System.out.println(user.getName() + " has id " + user.getId()
            + " is of age " + user.getAge());

The output indicates the below:

Response Status : 200
headers in response are : {Server=[Apache-Coyote/1.1], Content-Type=[application
/json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[Sat, 15 Jun 2013 12:17:
41 GMT]}
William has id 1 is of age 12

Here instead of dealing with the output object only, we have retrieved a representation of the HTTP response. The responseEntity class gives us access to headers and Status while the getBody method gives the output object. This object is generated by Spring's message converters from the actual response stream.
To test the Create User operation:

public User createUser(final User user) {
      return this.restTemplate.postForObject(userServiceUrl, user, User.class);
   }

The postForObject works similar to getForObject(). Only difference is that the second parameter here is the object that is written to the RequestStream. To test this method:

   User user = new User();
   user.setAge(21);
   user.setName("Robin");
   user = restClient.createUser(user);
   System.out.println("User created with id " + user.getId());

The output is :

013-06-15 17:53:16 DEBUG RestTemplate:78 - Created POST request for "
alhost:8080/SampleRest/api/user/"
2013-06-15 17:53:16 DEBUG RestTemplate:528 - Setting request Accept header to [a
pplication/json]
2013-06-15 17:53:16 DEBUG RestTemplate:592 - Writing [com.test.controller.User@1
114460] using [org.springframework.http.converter.json.MappingJacksonHttpMessage
]
2013-06-15 17:53:17 DEBUG RestTemplate:473 - POST request for ":
8080/SampleRest/api/user/" resulted in 200 (OK)
2013-06-15 17:53:17 DEBUG RestTemplate:78 - Reading [com.test.controller.User] a
s "application/json;charset=UTF-8" using [org.springframework.http.converter.jso
]
User created with id 3

Similarly for update and delete operations we have the below methods:

public void updateUser(final User user) {
      this.restTemplate.put(userServiceUrl + "{id}", user, user.getId());
   }

   public void deleteUser(final int id) {
      this.restTemplate.delete(userServiceUrl + "{id}", id);
   }

The two methods both have a void return type. However both PUT and DELETE are capable of returning response body. The RestTemplate does not support the same (I used Spring version 3.1.2) There is also the case where you may want to send some custom headers in the request. For that we need to use an instance of HttpEntity:

public void postWithHeaders(User user) {
      final HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_JSON);
      headers.add("custom", true + "");

      final HttpEntity wineRequest = new HttpEntity(user, headers);
      user = this.restTemplate.postForObject(userServiceUrl, wineRequest,
            User.class);
   }

Interestingly the ResponseEntity class that we used earlier extends from HttpEntity. Just to add - it is not a must to use this class.We could probably achieve the same using the tried and tested HttpClient from Apache.
Spring's RestTemplate class is simply one more way to create a REST client. I did find it easy to use though.

阅读(911) | 评论(0) | 转发(0) |
0

上一篇:java反射--注解的定义与运用以及权限拦截

下一篇:没有了

给主人留下些什么吧!~~