通过ADF Data Control 发布RESTFul 服务的资源
十月 23, 2008 in Oracle 融合中间件
前面2篇文章我们跟随Lucas一起基于RESTLet开发了Restful的Web服务,其中的数据使用的是静态的数据,这样的情景在实际的应用中比较少见,
一般都是通过Business Service层来隐藏数据库的持久层和Web服务,以更清晰的层次来发布资源。
下面我们使用ADF Model中的Data Control & Data Bindings功能来实现一个业务服务层(Business Service),
通过创建一个:Placeholder Data Control来实现,首先创建一个Note的数据类型,然后通过Placeholder Data Control来发布一个Note对象的集合。
应用中通过BindingContainer才能使用Data Control,BindingContainer负责进行应用程序和数据集合(collections)、数据操作(operations)之间的连接,
这样的连接称为数据绑定(Data Bindings),基于使用这些集合的方式,我们可以使用各种类型的数据绑定,
如:表格,列表和树。BindingContainer通常被页面绑定配置文件PageDefinition文件初始化,页面绑定配置文件包括了数据绑定的配置信息。
创建 placeholder data control
路径:Business Tier –> Placeholder Data Control
创建完ResourceDataPlaceHolder之后,从Data Controls属性窗口的上下文菜单中选择Create Placeholder Data Type
在创建Placeholder Data Type窗口中指定数据类型名称:Note;以及数据类型的属性:name, description, creationDate,切换到Sample Data标签页,输入静态的样例数据
创建完成之后,Data Control显示如下图:
打开我们在第一篇文章中创建的restful.jsp页面,从Data Control面板中拖动Note到页面上,然后选择创建一个Table组件,
创建完成之后会生成一个页面绑定文件叫做restfulPageDef.xml,它就是BindingContainer的设计时的配置文件,
它创建了一个基于ResourceDataPlaceHolder数据集合的迭代器,然后绑定到了一个Table来访问Data Control的数据,代码如下:
1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="UTF-8" ?> <table id="Note"><tbody></tbody></table> |
在DataBindings.cpx的文件中对页面绑定配置文件PageDefinition的定义:
1 |
配置ADF Binding Filter
上面通过拖拽来定义JSP页面,JDeveloper在web.xml文件中自动配置了ADF Binding Filter,过滤器会在web应用和BindingContainers交互之前初始化ADF Binding Context,
然而默认创建的是只处理*.jsp 和 *.jspx的相关请求,因此需要修改为*来处理RESTful服务的任何请求,修改URL匹配模式为:
1 2 3 4 | ADFBindingFilter
*
FORWARD
REQUEST |
使我们的应用能够访问Note table binding
如果在应用中我们需要在多个地方访问Note 表格绑定,那我们需要在一个集中的地方去处理获得表格的绑定,因此将这个方法放到我们的控制类RestfulAppliction中,
这个方法首先得到ADF的上下文ADFContext,绑定上下文BindingContext,然后从绑定容器BindingContainer中获得table binding
1 2 3 4 5 6 7 8 9 10 11 12 | public static JUCtrlRangeBinding getNotesTableBinding() { ADFContext ctx = ADFContext.getCurrent(); OracleExpressionEvaluatorImpl elev = (OracleExpressionEvaluatorImpl)ctx.getExpressionEvaluator(); HttpBindingContext data = (HttpBindingContext)elev.evaluate("${data}"); DCBindingContainer bc = data.findBindingContainer("com_oracleseeker_demo_restfulPageDef"); bc.refresh(DCBindingContainer.PREPARE_MODEL); JUCtrlRangeBinding tableBinding = (JUCtrlRangeBinding)bc.findNamedObject("Note"); return tableBinding; } |
从ADF Data Control中发布Notes资源
我们必须在资源类NotesResource中实现represent()方法来处理GET请求,然后返回数据。
添加类的私有变量:notesTableBinding
添加代码到构造函数中:
1 | notesTableBinding= RestfulApplication.getNotesTableBinding(); |
在represent()方法中循环处理TableBinding返回的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @Override
public Representation represent(Variant variant) throws ResourceException {
if (MediaType.TEXT_XML.equals(variant.getMediaType())) {
try {
DomRepresentation representation =
new DomRepresentation(MediaType.TEXT_XML);
Document doc = representation.getDocument();
Element root = doc.createElement("notes");
doc.appendChild(root);
RowIterator ri = notesTableBinding.getRowIterator();
ri.reset();
Row[] rows = ri.getAllRowsInRange();
for (Row row : rows) {
Element eltNote = doc.createElement("note");
Element eltName = doc.createElement("name");
eltName.appendChild(doc.createTextNode((String)row.getAttribute("name")));
eltNote.appendChild(eltName);
Element eltDescription = doc.createElement("description");
eltDescription.appendChild(doc.createTextNode((String)row.getAttribute("description")));
eltNote.appendChild(eltDescription);
Element eltCreationDate =
doc.createElement("creationDate");
eltCreationDate.appendChild(doc.createTextNode(((oracle.jbo.domain.Date)row.getAttribute("creationDate")).toString()));
eltNote.appendChild(eltCreationDate);
root.appendChild(eltNote);
}
doc.normalizeDocument();
return representation;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
} |
运行restful.jsp,修改URL指向资源/notes,运行如下的结果:
添加开始行和最大行的功能
一般在应用中调用Web服务都会进行分页,因此就会有一个页面显示数据多少行到多少行,
因此我们的URL看起来像是这样的:http://host:port/webapp/notes?start=26&maxRows=25
添加两个私有变量到资源类NotesResource中
1 2 | int startRow = 0; int maxRows = -1; |
在类的构造函数中获取请求URL中的开始行和最大行参数的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | String startRowParam = request.getResourceRef().getQueryAsForm().getFirstValue("start"); if (startRowParam != null) { startRow = Integer.parseInt(startRowParam); } else { startRow = 0; } String maxRowsParam = request.getResourceRef().getQueryAsForm().getFirstValue("maxRows"); if (maxRowsParam != null) { maxRows = Integer.parseInt(maxRowsParam); } else { maxRows = -1; } |
在represent()方法中加入限制
1 2 3 | ri.reset(); ri.setRangeSize(maxRows); ri.setRangeStart(startRow); |
在URL中添加参数:http://127.0.0.1:7101/oracleseeker-restful/notes?maxRows=2&start=1 运行结果:
上面三篇文章使用RestLet开源库来创建Restful 服务,同时利用JDeveloper 11g的新特性来发布数据。
资源链接
Publishing resources exposed by ADF Data Control in RESTful services using RestLet and JDeveloper 11g by Lucas Jellema
–
相关文章:
