PetStore REST服务的定义和实现
在Jazz Web应用中,开发者可以通过REST服务向Web客户端暴露服务器端提供的各种服务。在PetStore应用我们实现了REST服务IPetStoreRestService向Web UI提供其所需的功能。下面我们介绍IPetStoreRestService的定义和实现。
1.定义数据传输对象DTO
数据传输对象是指在客户端和服务器端进行数据交换用的数据对象,Web客户端调用REST服务的getXXX方法获取数据时,REST服务将调用RPC服务获取数据并将结果封装成一个DTO返回,Jazz平台会将其转换成一个JSON(JavaScript Object Notation)数组传递给Web客户端。
我们新建一个Ecore数据模型petstoreDTO.ecore来定义每个数据传输对象DTO,如Product对应的DTO模型如图 1所示:
图1. Product DTO
注意:与需要持久化的数据不同,DTO数据仅仅在传输中使用。所以在实现时,DTO模型的定义只需包含传递给客户端的数据内容,无需添加持久化相关的注解(annotation)。通过运行Jazz codegen,可以根据DTO模型生成对应的Java 类。
2.在com.ibm.petstore.common中定义REST服务接口,如清单10所示。
清单10. REST服务接口定义
public interface IPetStoreRestService extends ITeamModelledRestService{
public ProductDTO[] getAllProductDTOs() throws TeamRepositoryException;
public ProductDTO postProduct(ParametersPublishProduct param) throws TeamRepositoryException;
public static final class ParametersPublishProduct implements IParameterWrapper{
public String categoryId;
public String name;
public String description;
public String price;
public String tags;//tag1,tag2,tag3,...,tagN
public String sellerName;
public String sellerAddress;
public String sellerEmail;
}
……
}
注意:REST服务接口定义需要继承ITeamModelledRestService, Jazz中所有的REST服务必须集成此接口。
各个方法名称遵循REST风格getXXX、postXXX……,分别用于处理客户端对应的get、post等请求响应。
每个postXXX方法的参数都需要运用IParameterWrapper来进行参数封装
每个方法都需要抛出TeamRepositoryException。
3.在com.ibm.petstore.common的plugin.xml中进行REST服务的注册,如清单11所示。
清单11. REST服务接口注册
<service
kind="MODELLED_REST"
name="PetStore Item Rest Service"
uri="com.ibm.petstore.common.service.rest.IPetStoreRestService"
version="1">
</service>
注意:“kind”属性为“MODELLED_REST”,这样Jazz平台就能将其注册为REST服务。
4.在com.ibm.petstore.service中实现REST服务,如清单12所示。
清单12. REST服务实现
public class PetStoreRestService extends AbstractService implements IPetStoreRestService {
……
}
这里我们通过PetStoreRestService中宠物发布postProduct和获取所有宠物getAllProductDTOs的实现介绍REST服务如何实现与Web客户端的数据交互,如清单13所示。
清单13. 响应浏览器post事件
public ProductDTO postProduct(ParametersPublishProduct param) throws
TeamRepositoryException {
……
IProduct product=getService(IProductService.class).createProduct(0,
param.name, param.description, category, seller, price, tags);
product=getService(IProductService.class).saveProduct(product);
return productToDTO(product);
}
public ProductDTO[] getAllProductDTOs() throws TeamRepositoryException {
IProduct[] products=getService(IProductService.class).findAllProducts();
ProductDTO[] dtos=new ProductDTO[products.length];
for(int i=0;i<products.length;i++)
dtos[i]=productToDTO(products[i]);
return dtos;
}
可以看到,postProduct方法接收客户端传来的Http Request 参数并调用RPC服务IProductService创建和保存宠物,最终将创建的宠物转换为DTO返回给客户端。getAllProductDTOs方法通过调用IProductService获取所有的产品并将它们转换为DTO数组返回给客户端。productToDTO方法实现如清单 14所示:
清单14. 向客户端返回DTO数据
private ProductDTO productToDTO(IProduct product)
throws TeamRepositoryException {
ProductDTO dto = RestFactory.eINSTANCE.createProductDTO();
dto.setId(product.getId());
dto.setName(product.getName());
dto.setDescription(product.getDescription());
dto.setPrice(product.getPrice());
dto.setTags(product.getTags());
CategoryDTO cdto = categoryToDTO((ICategory) getService(
IRepositoryItemService.class).fetchItem(product.getCategory(),
null));
dto.setCategory(cdto);
SellerDTO sdto = sellerToDTO((ISeller) getService(
IRepositoryItemService.class).fetchItem(product.getSeller(),
null));
dto.setSeller(sdto);
return dto;
}