领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在之前的一篇文章中,我写了关于我们添加到 Spring @MVC 3.0 版本中的 REST 功能。后来,Alef撰写了关于使用引入的功能向 Pet Clinic 应用程序添加 Atom 视图的文章。在这篇文章中,我想介绍我们在里程碑 2 中添加的客户端功能。
模板的主要入口点以六种主要 HTTP 方法命名
这些方法的名称清楚地表明了它们调用的 HTTP 方法,而名称的第二部分指示了返回的内容。例如,getForObject()将执行 GET 操作,将 HTTP 响应转换为您选择的对象类型,并返回该对象。postForLocation将执行 POST 操作,将给定对象转换为 HTTP 请求,并返回响应 HTTP Location 标头,其中包含新创建的对象的位置。正如您所看到的,这些方法试图强制执行 REST 最佳实践。
这些方法中的每一个都将 URI 作为第一个参数。该 URI 可以是URI 模板,并且可以使用变量将模板扩展为普通 URI。模板变量可以通过两种形式传递:作为字符串变量参数数组或作为 Map<String, String>。字符串 varargs 变体按顺序扩展给定的模板变量,因此
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21");
将在以下位置执行 GET 操作:http://example.com/hotels/42/bookings/21。映射变体根据变量名称扩展模板,因此在使用多个变量时或当单个变量多次使用时更有用。例如
Map<String, String> vars = new HashMap<String, String>();
vars.put("hotel", "42");
vars.put("booking", "21");
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class, vars);
也将执行以下 GET 操作:http://example.com/hotels/42/rooms/42.
<photos page="2" pages="89" perpage="10" total="881">
<photo id="2636" owner="47058503995@N01"
secret="a123456" server="2" title="test_04"
ispublic="1" isfriend="0" isfamily="0" />
<photo id="2635" owner="47058503995@N01"
secret="b123456" server="2" title="test_03"
ispublic="0" isfriend="1" isfamily="1" />
<photo id="2633" owner="47058503995@N01"
secret="c123456" server="2" title="test_01"
ispublic="1" isfriend="0" isfamily="0" />
<photo id="2610" owner="12037949754@N01"
secret="d123456" server="2" title="00_tall"
ispublic="1" isfriend="0" isfamily="0" />
</photos>
使用 RestTemplate,检索此类文档非常简单
final String photoSearchUrl =
"http://www.flickr.com/services/rest?method=flickr.photos.search&api+key={api-key}&tags={tag}&per_page=10";
Source photos = restTemplate.getForObject(photoSearchUrl, Source.class, apiKey, searchTerm);
其中apiKey和searchTerm是命令行上给出的两个字符串。此方法使用SourceHttpMessageConverter将 HTTP XML 响应转换为javax.xml.transform.Source(请注意,SourceHttpMessageConverter 是在我们发布 Spring 3.0 M2 后不久引入的,因此您需要获取最新的快照(或即将推出的 M3)才能使用它。下面提供的示例项目设置为通过 Maven 检索这些快照)。
List<BufferedImage> imageList = xpathTemplate.evaluate("//photo", photos, new NodeMapper() {
public Object mapNode(Node node, int i) throws DOMException {
Element photo = (Element) node;
Map<String, String> variables = new HashMap<String, String>(3);
variables.put("server", photo.getAttribute("server"));
variables.put("id", photo.getAttribute("id"));
variables.put("secret", photo.getAttribute("secret"));
String photoUrl = "http://static.flickr.com/{server}/{id}_{secret}_m.jpg";
return restTemplate.getForObject(photoUrl, BufferedImage.class, variables);
}
});
例如,给定上面给出的 XML 文档,imageList将包含 4 张图像。检索到的第一张图像的 URL 将为http://static.flickr.com/2/2636_ a123456_m.jpg,第二个是http://static.flickr.com/2/2635_ b123456_m.jpg,等等。
public class BufferedImageHttpMessageConverter implements HttpMessageConverter<BufferedImage> {
public List<MediaType> getSupportedMediaTypes() {
return Collections.singletonList(new MediaType("image", "jpeg"));
}
public boolean supports(Class<? extends BufferedImage> clazz) {
return BufferedImage.class.equals(clazz);
}
public BufferedImage read(Class<BufferedImage> clazz, HttpInputMessage inputMessage) throws IOException {
return ImageIO.read(inputMessage.getBody());
}
public void write(BufferedImage image, HttpOutputMessage message) throws IOException {
throw new UnsupportedOperationException("Not implemented");
}
}
请注意,我们没有实现write()因为我们不是上传图像,而只是下载它们。现在我们只需要将此转换器插入 RestTemplate。我们在 Spring 应用程序上下文中执行此操作
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="flickrClient" class="com.springsource.samples.resttemplate.FlickrClient">
<constructor-arg ref="restTemplate"/>
<constructor-arg ref="xpathTemplate"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="com.springsource.samples.resttemplate.BufferedImageHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="xpathTemplate" class="org.springframework.xml.xpath.Jaxp13XPathTemplate"/>
</beans>
JFrame frame = new JFrame(searchTerm + " photos");
frame.setLayout(new GridLayout(2, imageList.size() / 2));
for (BufferedImage image : imageList) {
frame.add(new JLabel(new ImageIcon(image)));
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
这给了我们以下内容
总的来说,我希望这篇文章向您展示了使用 RestTemplate 与 HTTP 服务器交互是多么简单。只需不到 30 行 Java 代码,我们就创建了一个 GUI,用于显示每个人最喜欢的鸟类:企鹅!查看RestTemplate,并告诉我们您的想法!