[导入][AppFuse] AppFuse使用手记--DWR(十) [原]
在AppFuse实现级联下拉列表最方便的方式是使用DWR了,AppFuse默认就支持DWR。web.xml里DWR配置部分开始就存在了。
web.xml:
有一点非常要注意到,web.xml里staticFilter默认是包含dwr部分了,如果我们不屏蔽掉dwr这部分,获得dwr的响应是不正常的。在我没有屏蔽的时候,DWR调用java是可以的,java返回的内容也是正常的,但是dwr执行回调函数时怎样也没有反映。这个问题困扰了我很久,直到发现这个配置后屏蔽调就好了。
完成DWR的配置,我们就可以通过DWR调用我们的Java代码实现级联下拉列表了。刚开始我想通过DWR直接调Action来实现,但是调用Action时发现通过Spring注入的Manager和DAO是没有办法获得的。DWR官方号称是整合了Struts,但是文档里的例子只举到怎么调用ActionForm,Struts2都已经取消了烦人的ActionForm,还调他做甚?不过,有一句提示:“一个比较好方法是重构你想调用的Action,提取出Action的逻辑。DWR和你的Action就可以同时调用相同的方法了。”所以,用DWR调用逻辑的Service看来是比较可行的办法。
我们可以参照AppFuse生产的dwr.xml里UserManager的实现,来实现我们的Service。
CompanyService:
CompanyServiceImpl:
同时把上面的Service添加到Spring的配置文件里。
applicationContext.xml:
DWR的Creators支持Spring,我们可以通过Spring的方式创建。
dwr.xml:
这样我们通过 http://localhost:8080/[ YOUR-WEBAPP ]/dwr,就可以看到生产的Javascript代码了。
我们在JSP里通过回调函数就可以实现级联下拉列表了。
JSP:
下面是通过HttpWatch扑获的数据。我们可以看到DWR是发出了什么样的请求,以及返回的数据结构。
HTTP Request:
POST Data:
Content:
文章来源: http://heyday.blogcn.com/diary,15807434.shtml
web.xml:
1
<
servlet
>
2
<
servlet-name
>
dwr-invoker
</
servlet-name
>
3
<
servlet-class
>
org.directwebremoting.servlet.DwrServlet
</
servlet-class
>
4
<
init-param
>
5
<
param-name
>
debug
</
param-name
>
6
<
param-value
>
true
</
param-value
>
7
</
init-param
>
8
</
servlet
>
9
10
<
servlet-mapping
>
11
<
servlet-name
>
dwr-invoker
</
servlet-name
>
12
<
url-pattern
>
/dwr/*
</
url-pattern
>
13
</
servlet-mapping
>

2

3

4

5

6

7

8

9

10

11

12

13

有一点非常要注意到,web.xml里staticFilter默认是包含dwr部分了,如果我们不屏蔽掉dwr这部分,获得dwr的响应是不正常的。在我没有屏蔽的时候,DWR调用java是可以的,java返回的内容也是正常的,但是dwr执行回调函数时怎样也没有反映。这个问题困扰了我很久,直到发现这个配置后屏蔽调就好了。
1
<
filter
>
2
<
filter-name
>
staticFilter
</
filter-name
>
3
<
filter-class
>
org.appfuse.webapp.filter.StaticFilter
</
filter-class
>
4
<
init-param
>
5
<
param-name
>
includes
</
param-name
>
6
<!--
<param-value>/scripts/dojo/*,/dwr/*</param-value>
-->
7
<
param-value
>
/scripts/dojo/*
</
param-value
>
8
</
init-param
>
9
</
filter
>

2

3

4

5

6

7

8

9

完成DWR的配置,我们就可以通过DWR调用我们的Java代码实现级联下拉列表了。刚开始我想通过DWR直接调Action来实现,但是调用Action时发现通过Spring注入的Manager和DAO是没有办法获得的。DWR官方号称是整合了Struts,但是文档里的例子只举到怎么调用ActionForm,Struts2都已经取消了烦人的ActionForm,还调他做甚?不过,有一句提示:“一个比较好方法是重构你想调用的Action,提取出Action的逻辑。DWR和你的Action就可以同时调用相同的方法了。”所以,用DWR调用逻辑的Service看来是比较可行的办法。
我们可以参照AppFuse生产的dwr.xml里UserManager的实现,来实现我们的Service。
CompanyService:
1
package
com.reda.app.service;
2
3
import
java.util.Map;
4
public
interface
CompanyService
{
5
6
public Map selectInput(String companyTypeId);
7
}

2

3

4



5

6

7

CompanyServiceImpl:
1
package
com.reda.app.service.impl;
2
3
import
com.reda.app.service.CompanyService;
4
import
com.reda.app.model.Company;
5
import
com.reda.app.model.CompanyType;
6
import
com.reda.app.dao.CompanyDao;
7
8
import
java.util.List;
9
import
java.util.Map;
10
import
java.util.HashMap;
11
12
public
class
CompanyServiceImpl
implements
CompanyService
{
13
14
private CompanyDao companyDao;
15
16
public void setCompanyDao(CompanyDao companyDao)
{
17
this.companyDao = companyDao;
18
}
19
20
public Map selectInput(String companyTypeId)
{
21
Company company = new Company();
22
CompanyType companyType = new CompanyType();
23
companyType.setTypeId(new Long(companyTypeId));
24
company.setCompanyType(companyType);
25
List list = companyDao.select(company);
26
27
Map<String, String> map = new HashMap<String, String>();
28
29
for (Object aList : list)
{
30
map.put(((Company) aList).getCompanyId().toString(), ((Company) aList).getCompanyName());
31
}
32
33
return map;
34
}
35
36
}

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

同时把上面的Service添加到Spring的配置文件里。
applicationContext.xml:
1
<
bean
id
="companyService"
class
="com.reda.app.service.impl.CompanyServiceImpl"
>
2
<
property
name
="companyDao"
ref
="companyDao"
/>
3
</
bean
>

2

3

DWR的Creators支持Spring,我们可以通过Spring的方式创建。
dwr.xml:
1
<
create
creator
="spring"
javascript
="CompanyService"
>
2
<
param
name
="class"
value
="com.reda.app.service.CompanyService"
/>
3
<
param
name
="beanName"
value
="companyService"
/>
4
</
create
>

2

3

4

这样我们通过 http://localhost:8080/[ YOUR-WEBAPP ]/dwr,就可以看到生产的Javascript代码了。
我们在JSP里通过回调函数就可以实现级联下拉列表了。
JSP:
1
<
script
type
='text/javascript'
src
='<%=request.getContextPath()%
>
/dwr/interface/CompanyService.js'>
</
script
>
2
<
script
type
='text/javascript'
src
='<%=request.getContextPath()%
>
/dwr/engine.js'>
</
script
>
3
<
script
type
='text/javascript'
src
='<%=request.getContextPath()%
>
/dwr/util.js'>
</
script
>
4
5
<
script
type
='text/javascript'
>
6
function searchCompany(companyTypeId)
{
7
dwr.util.removeAllOptions("person.company.companyId");
8
CompanyService.selectInput(companyTypeId, function(data)
{
9
dwr.util.addOptions("person.company.companyId", data);
10
});
11
}
12
</
script
>
13
14
<
s:label
for
="personForm_company_companyType"
value
="%{getText('companyType.typeName')}"
cssClass
="desc"
/>
15
<
s:select
name
="person.company.companyType.typeId"
list
="companyTypeList"
listKey
="typeId"
listValue
="typeName"
16
onchange
="searchCompany(this.value)"
></
s:select
>
17
<
s:label
for
="personForm_company_companyName"
value
="%{getText('company.companyName')}"
cssClass
="desc"
/>
18
<
s:select
name
="person.company.companyId"
list
="companyList"
listKey
="companyId"
19
listValue
="companyName"
></
s:select
>
20



2



3



4

5



6



7

8



9

10

11

12

13

14

15

16

17

18

19

20

下面是通过HttpWatch扑获的数据。我们可以看到DWR是发出了什么样的请求,以及返回的数据结构。
HTTP Request:
http://localhost:8080/reda/dwr/call/plaincall/CompanyService.selectInput.dwr;jsessionid=41C3CAEA0AEDFA7288EBFFBA0A5543BB
POST Data:
callCount=1
page=/reda/persons.html;jsessionid=41C3CAEA0AEDFA7288EBFFBA0A5543BB
httpSessionId=1CBB46415786B48DC00EB91C0BA0BB23
scriptSessionId=658A71BBBEB17A34CB847C6A46EEA00581
c0-scriptName=CompanyService
c0-methodName=selectInput
c0-id=0
c0-param0=string:8
batchId=0
page=/reda/persons.html;jsessionid=41C3CAEA0AEDFA7288EBFFBA0A5543BB
httpSessionId=1CBB46415786B48DC00EB91C0BA0BB23
scriptSessionId=658A71BBBEB17A34CB847C6A46EEA00581
c0-scriptName=CompanyService
c0-methodName=selectInput
c0-id=0
c0-param0=string:8
batchId=0
Content:
//#DWR-INSERT
//#DWR-REPLY
dwr.engine._remoteHandleCallback('0','0',{'74':"\u5B9C\u6625\u6E29\u548C\u5B9E\u4E1A\u6709\u9650\u516C\u53F8",'63':"\u682A\u6D32\u5E02\u660E\u65E5\u73BB\u7483\u94A2\u5382",'70':"\u6C38\u5DDE\u5E02\u7F8E\u96C5\u73BB\u7483\u94A2\u5236\u54C1\u5382",'75':"\u5B9C\u6625\u73A9\u5177\u5382",'58':"\u957F\u6C99\u66AE\u4E91\u4E9A\u592A\u6C7D\u8F66\u5185\u9970\u4EF6\u5382",'64':"\u682A\u6D32\u5E02\u752C\u7CA4\u4E0D\u9508\u94A2\u884C",'69':"\u91B4\u9675\u5E02\u65B0\u5EFA\u73BB\u7483\u94A2\u5382",'60':"\u682A\u6D32\u5F18\u71D5\u73BB\u7483\u94A2\u5382",'71':"\u53CC\u724C\u53BF\u73BB\u7483\u94A2\u6709\u9650\u516C\u53F8",'57':"\u6E56\u5357\u4E9A\u592A\u5B9E\u4E1A\u6709\u9650\u516C\u53F8",'65':"\u682A\u6D32\u5E02\u67F3\u9F99\u73BB\u7483\u94A2\u5236\u54C1\u6709\u9650\u8D23\u4EFB\u516C\u53F8",'76':"\u5B9C\u6625\u5E02\u8881\u5DDE\u946B\u6E90\u673A\u68B0\u6709\u9650\u516C\u53F8",'59':"\u957F\u6C99\u798F\u51EF\u6C7D\u8F66\u8F66\u8EAB\u6709\u9650\u516C\u53F8",'72':"\u840D\u4E61\u6C7D\u9A70\u5B9E\u4E1A\u516C\u53F8",'61':"\u682A\u6D32\u5E02\u5BCC\u4E3D\u6765\u73BB\u7483\u94A2\u6709\u9650\u516C\u53F8",'68':"\u91B4\u9675\u5E02\u6E58\u4E1C\u73BB\u7483\u94A2\u5382",'56':"\u6E56\u5357\u94F6\u6CB3\u73BB\u7483\u6750\u6599\u5F00\u53D1\u6709\u9650\u516C\u53F8",'77':"\u8D63\u897F\u5316\u5DE5\u5382",'62':"\u682A\u6D32\u5E02\u81EA\u6765\u6C34\u516C\u53F8\u73BB\u7483\u94A2\u5382",'73':"\u840D\u4E61\u5E02\u5317\u6865\u73BB\u7483\u94A2\u5236\u54C1\u5382",'66':"\u91B4\u9675\u5E02\u4E07\u901A\u516C\u53F8",'67':"\u91B4\u9675\u5E02\u798F\u661F\u73BB\u7483\u94A2\u5382"});
//#DWR-REPLY
dwr.engine._remoteHandleCallback('0','0',{'74':"\u5B9C\u6625\u6E29\u548C\u5B9E\u4E1A\u6709\u9650\u516C\u53F8",'63':"\u682A\u6D32\u5E02\u660E\u65E5\u73BB\u7483\u94A2\u5382",'70':"\u6C38\u5DDE\u5E02\u7F8E\u96C5\u73BB\u7483\u94A2\u5236\u54C1\u5382",'75':"\u5B9C\u6625\u73A9\u5177\u5382",'58':"\u957F\u6C99\u66AE\u4E91\u4E9A\u592A\u6C7D\u8F66\u5185\u9970\u4EF6\u5382",'64':"\u682A\u6D32\u5E02\u752C\u7CA4\u4E0D\u9508\u94A2\u884C",'69':"\u91B4\u9675\u5E02\u65B0\u5EFA\u73BB\u7483\u94A2\u5382",'60':"\u682A\u6D32\u5F18\u71D5\u73BB\u7483\u94A2\u5382",'71':"\u53CC\u724C\u53BF\u73BB\u7483\u94A2\u6709\u9650\u516C\u53F8",'57':"\u6E56\u5357\u4E9A\u592A\u5B9E\u4E1A\u6709\u9650\u516C\u53F8",'65':"\u682A\u6D32\u5E02\u67F3\u9F99\u73BB\u7483\u94A2\u5236\u54C1\u6709\u9650\u8D23\u4EFB\u516C\u53F8",'76':"\u5B9C\u6625\u5E02\u8881\u5DDE\u946B\u6E90\u673A\u68B0\u6709\u9650\u516C\u53F8",'59':"\u957F\u6C99\u798F\u51EF\u6C7D\u8F66\u8F66\u8EAB\u6709\u9650\u516C\u53F8",'72':"\u840D\u4E61\u6C7D\u9A70\u5B9E\u4E1A\u516C\u53F8",'61':"\u682A\u6D32\u5E02\u5BCC\u4E3D\u6765\u73BB\u7483\u94A2\u6709\u9650\u516C\u53F8",'68':"\u91B4\u9675\u5E02\u6E58\u4E1C\u73BB\u7483\u94A2\u5382",'56':"\u6E56\u5357\u94F6\u6CB3\u73BB\u7483\u6750\u6599\u5F00\u53D1\u6709\u9650\u516C\u53F8",'77':"\u8D63\u897F\u5316\u5DE5\u5382",'62':"\u682A\u6D32\u5E02\u81EA\u6765\u6C34\u516C\u53F8\u73BB\u7483\u94A2\u5382",'73':"\u840D\u4E61\u5E02\u5317\u6865\u73BB\u7483\u94A2\u5236\u54C1\u5382",'66':"\u91B4\u9675\u5E02\u4E07\u901A\u516C\u53F8",'67':"\u91B4\u9675\u5E02\u798F\u661F\u73BB\u7483\u94A2\u5382"});
文章来源: http://heyday.blogcn.com/diary,15807434.shtml