首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

在 Apache Wink 中使用 Dojo Grid 和 Dojo Tree 小部件(2)

在 Apache Wink 中使用 Dojo Grid 和 Dojo Tree 小部件(2)

编写自定义服务提供方程序 Wink 框架支持默认服务提供方程序,比如 JavaScript Object Notation (JSON) 和 XML。Dojo 小部件接受网格和树格式的数据,但是它们按不能这种格式使用,因为 Wink 框架生成的输出不能匹配 Dojo 标准。要使用 Wink,您需要通过编写自定义服务提供方程序以及将它们插入框架来扩展框架。默认情况下,Apache Wink 支持以下表示:
  • JSON
  • RSS
  • MultiPart
  • APP
  • CSV
  • OpenSearch
  • Atom
  • HTML
要支持上述之外的表示,您需要编写自定义服务提供方程序。下一节介绍如何编写一个自定义服务提供方程序来支持网格表示,以便于被 Dojo 小部件所理解。
针对 Dojo 网格的自定义服务提供方程序 要出创建一个自定义服务提供方程序 JSONGridProvider,从清单 5 中的代码开始。
清单 5. JSON 网格自定义服务提供方程序
1
2
3
4
5
@Provider
@Produces(value = { "application/json_grid" })
public class JsonGridProvider implements MessageBodyWriter<DojoList> {
...
}




@Provider 注解将该类声明为服务提供方程序类。@Produces 定义输出内容类型,用于生成输出。通过为其属性(在本例中是 application/json_grid)值提供一个自定义内容类型,默认 MIME 类型被替代。对于 JSONGridProvider,创建一个新的自定义 MIME 类型,比如 application/json_grid。对于要以网格格式生成 JSON 的 JSONGridProvider ,MessageBodyWriter 接口必须被重写。
一个自定义服务提供方程序必须重写 MessageBodyWriter 接口的两个方法:isWritable() 和                writeTo()。清单 6 显示 JsonGridProvider 重写的一个示例。
清单 6.  为 JSON 网格服务提供方程序重写 isWriteable
1
2
3
4
public boolean isWriteable(Class<?> inputClass, Type type,
Annotation[] annotations, MediaType mediaType) {
return inputClass == DojoList.class;
}




在清单 6 的代码片段中,当 DojoList 类被传入时,将返回 true。Wink 框架然后选择自定义的 JsonGridProvider 来进行 XML 编组(marshalling)。
清单 7 中的代码将 DojoList(列表对象)的实例编组成 JSON。
清单 7. 为 JSON 网格服务提供方程序重写 isWriteTo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Create a new instance JAXbContext on given context path.

jc = JAXBContext.newInstance("rest.resource");
OutputStream tempOs = new ByteArrayOutputStream();
Marshaller ms = jc.createMarshaller();
HashMap<String, String> namespaceMap = new HashMap<String, String>();
namespaceMap.put("http://www.w3.org/2001/XMLSchema-instance",
“xmlns”);
namespaceMap.put("http://www.w3.org/2001/XMLSchema-instance",
"xmlns.type");
System.out.println("Size is "+namespaceMap.size());

XMLOutputFactory factory = new MappedXMLOutputFactory(namespaceMap);
XMLStreamWriter xsw = factory.createXMLStreamWriter(tempOs);
ms.marshal(list, xsw);




清单 8  显示编组程序生成的 JSON
清单  8. JSON 网格服务提供方程序的 JSON 输出
1
2
3
4
5
6
7
{"dojoItems":{"items":[{"@xmlns.type.type":"employee","id":"001",
"name":"Manager","manager":true,"sex":"male","age":35},
                   {"@xmlns.type.type":"employee","id":"002",
"name":"developer","manager":false,"sex":"male","age":25}],
"endRecordIndex":2,
"totalRecords":2,
"startRecordIndex":1}}




清单 8 中的输出有 @xmlns.type.type 属性。您需要通过删除标记来格式化输出,清单 9 中的代码片段取代所有出现 @xmlns.type.type 属性的地方,生成格式化输出。   
清单  9. 格式化 JSON 输出
1
2
3
4
5
6
7
8
private String replaceAll(String jsonString) {
         
String replacePattern = "\"@xmlns.type[a-z,A-Z,:,.,\"]*?,”;
Pattern pattern = Pattern.compile(replacePattern);
Matcher matcher = pattern.matcher(jsonString);
return matcher.replaceAll(“”);

    }




该函数是在 writeTo 方法中调用,因此,JSON 输出不使用 @xmlns.type.type 属性及其值来进行格式化。调用清单 9 中的函数之后生成的 JSON 输出在清单 10 显示。
清单  10. 格式化的 JSON 输出
1
2
3
4
5
{"dojoItems":{"items":[{"id":"001","name":"Manager","manager":true,"sex":"male","age":35},
{"id":"002","name":"developer","manager":false,"sex":"male","age":25}],
"endRecordIndex":2,
"totalRecords":2,
"startRecordIndex":1}}




从清单 10 中生成的 JSON 输出提取 items 属性及其值,如清单 11 所示。
清单 11. 提取 items 标签
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
40
41
42
43
44
45
46
47
48
49
int index = replacedJsonString.indexOf(":");
int end = replacedJson-String.lastIndexOf("}");
if (replacedJsonString.indexOf("items") > 0) {
if (index > 0) {

/*If  size is equal to 1, then square
brackets will not appear,
so add square brackets */

if(list.getItems().size() == 1)
{                       
/*extracting json grid format*/     
      
String itemsString = replacedJsonString.substring(index + 1, end);
debug(methodName, "jsonString itemsString=" + itemsString);
os.write(replaceWithParenthesisForSingleItem(itemsString,list).getBytes());

}
                                                                     
else

{
/*extracting json grid format and   
writing to outputStream*/

os.write(replacedJsonString.substring(index + 1, end)
.getBytes());
}

} else {
/*writing the replacedJsonString  into  
outputStream*/

os.write(replacedJsonString.getBytes());
}

} else {

// For an empty list, items tag won’t be present.
// But dojoWidget Requires it so adding it here.

String emptJsonString = “{items:[],startRecordIndex:" + "0"
•   ", endRecordIndex:" + "0" + ",totalRecords:" + "0"
                        + "}";
os.write(emptJsonString.getBytes());
}
os.close();
xsw.close();
tempOs.close();




如果条目列表中只有一项,那么生成的 JSON 将没有方括号([]),而您必须对其做一些特殊处理。除此之外,其他情况下生成的带有方括号的 JSON 输出都在清单中标出了。清单 12 显示了只有一个条目时如何添加方括号。
清单 12. 如果条目数为 1 添加 []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private String replaceWithParenthesisForSingleItem(String jsonString,DojoList list) {
         
final String methodName = "replaceWithParenthesisForSingleItem";
int firstColonIndex = jsonString.indexOf(":");
int endRecordIndex = jsonString.indexOf("endRecordIndex");      
int flowerBracketBeforeEndRecordIndexString = jsonString
.lastIndexOf("}",endRecordIndex);
String jsonObject = jsonString.substring(firstColonIndex + 1,
flowerBracketBeforeEndRecordIndexString + 1);
String replaceString = "{items:[" + jsonObject + "],startRecordIndex:"
•   list.getStartRecordIndex() + ", endRecordIndex:" + list.getEndRecordIndex() + ",
totalRecords:" + list.getTotalRecords()+ "}";      
System.out.println("jsonString after replace=" + replaceString);
return replaceString;

}




清单 13 显示了 JSON 网格服务提供方程序的最终格式化输出,它可被发送到任何 Dojo 网格客户端。Dojo 网格客户端可直接向用户显示生成的输出。
清单 13. 最终 JSON 网格输出
1
2
3
{"items":[{"id":"001","name":"Manager","manager":true,"sex":"male","age":35},
{"id":"002","name":"developer","manager":false,"sex":"male","age":25}],
"endRecordIndex":2,"totalRecords":2,"startRecordIndex":1}

返回列表