上篇文章介绍了程序整合的准备工作、结合MarshallingView视图完成jaxb2转换XML、xStream转换XML工作,这次将介绍castor、jibx转换XML。
还有MappingJacksonView用Jackson转换JSON,自己拓展AbstractView定义Jsonlib的视图完成JSON-lib转换JSON。
上一篇文章: http://www.cnblogs.com/hoojo/archive/2011/04/29/2032571.html
四、 用 Castor 转换 XML
1、 castor可以通过一个mapping.xml文件对即将转换的Java对象进行描述,然后可以将Java对象按照描述的情况输出XML内容。利用castor转换xml需要添加如下jar包:
如果你还不清楚castor,可以阅读:
for csblogs: http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html
for csdn: http://blog.csdn.net/IBM_hoojo/archive/2011/04/25/6360916.aspx
2、 你需要在dispatcher.xml中添加castor的相关视图,配置如下:
<
--
继承MarshallingView
,
重写locateToBeMarshalled方法
;
解决对象添加到ModelAndView中
,
转换后的xml是BindingResult信息的bug
--
>
<
bean
name
="castorMarshallingView"
class
="com.hoo.veiw.xml.OverrideMarshallingView"
>
<
property
name
="marshaller"
>
<
bean
class
="org.springframework.oxm.castor.CastorMarshaller"
>
<
property
name
="mappingLocations"
>
<
array
>
<
value
>
classpath:mapping.xml
</
value
>
</
array
>
</
property
>
<
property
name
="encoding"
value
="UTF-8"
/>
</
bean
>
</
property
>
</
bean
>
mapping.xml配置
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<!
DOCTYPE
mapping
PUBLIC
"-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd"
>
<
mapping
>
<
class
name
="com.hoo.entity.Account"
auto-complete
="true"
>
<
map-to
xml
="Account"
/>
<
field
name
="id"
type
="integer"
>
<
bind-xml
name
="id"
node
="attribute"
/>
</
field
>
<
field
name
="name"
type
="string"
>
<
bind-xml
name
="name"
node
="element"
/>
</
field
>
<
field
name
="email"
type
="string"
>
<
bind-xml
name
="email"
node
="element"
/>
</
field
>
<
field
name
="address"
type
="string"
>
<
bind-xml
name
="address"
node
="element"
/>
</
field
>
<
field
name
="brithday"
type
="com.hoo.entity.Brithday"
>
<
bind-xml
name
="生日"
node
="element"
/>
</
field
>
</
class
>
<
class
name
="com.hoo.entity.Brithday"
auto-complete
="true"
>
<
map-to
xml
="brithday"
/>
<
field
name
="brithday"
type
="string"
>
<
bind-xml
name
="brithday"
node
="attribute"
/>
</
field
>
</
class
>
<
class
name
="com.hoo.entity.MapBean"
auto-complete
="true"
>
<
field
name
="map"
collection
="map"
>
<
bind-xml
name
="map"
>
<
class
name
="org.exolab.castor.mapping.MapItem"
>
<
field
name
="key"
type
="java.lang.String"
>
<
bind-xml
name
="key"
node
="attribute"
/>
</
field
>
<
field
name
="value"
type
="com.hoo.entity.Account"
>
<
bind-xml
name
="value"
auto-naming
="deriveByClass"
/>
</
field
>
</
class
>
</
bind-xml
>
</
field
>
</
class
>
<
class
name
="com.hoo.entity.ListBean"
auto-complete
="true"
>
<
map-to
xml
="listBean"
/>
<
field
name
="list"
collection
="arraylist"
type
="com.hoo.entity.Account"
>
<
bind-xml
name
="beans"
auto-naming
="deriveByClass"
/>
</
field
>
<
field
name
="name"
type
="string"
/>
</
class
>
<
class
name
="com.hoo.entity.AccountArray"
auto-complete
="true"
>
<
map-to
xml
="account-array"
/>
<
field
name
="size"
type
="int"
/>
<
field
name
="accounts"
collection
="array"
type
="com.hoo.entity.Account"
>
<
bind-xml
name
="accounts"
auto-naming
="deriveByClass"
/>
</
field
>
</
class
>
</
mapping
>
关于mapping.xml配置的介绍,你可以参考 http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html
这篇文章的第三栏目。
3、 在使用Spring的MarshallingView的时候,转换的xml结果有时候会带有BindingResult对象的信息。所以解决办法是重写MarshallingView里面的locateToBeMarshalled方法,这样就可以解决了。下面是重新MarshallingView的class代码:
package
com.hoo.veiw.xml;
import
java.util.Map;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.springframework.beans.BeansException;
import
org.springframework.oxm.Marshaller;
import
org.springframework.validation.BindingResult;
import
org.springframework.web.servlet.view.xml.MarshallingView;
/**
* <b>function:</b>继承MarshallingView,重写locateToBeMarshalled方法;
* 解决对象添加到ModelAndView中,转换后的xml是BindingResult信息的bug
* @author hoojo
* @createDate 2010-11-29 下午05:58:45
* @file OverrideMarshallingView.java
* @package com.hoo.veiw.xml
* @project Spring3
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public
class
OverrideMarshallingView
extends
MarshallingView {
private
Marshaller marshaller;
private
String modelKey;
public
OverrideMarshallingView() {
super
();
}
public
OverrideMarshallingView(Marshaller marshaller) {
super
(marshaller);
this
.marshaller = marshaller;
}
public
void
setMarshaller(Marshaller marshaller) {
super
.setMarshaller(marshaller);
this
.marshaller = marshaller;
}
public
void
setModelKey(String modelKey) {
super
.setModelKey(modelKey);
this
.modelKey = modelKey;
}
@Override
protected
void
initApplicationContext()
throws
BeansException {
super
.initApplicationContext();
}
@SuppressWarnings(
"unchecked"
)
@Override
protected
void
renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response)
throws
Exception {
super
.renderMergedOutputModel(model, request, response);
}
@SuppressWarnings(
"unchecked"
)
@Override
protected
Object locateToBeMarshalled(Map model)
throws
ServletException {
if
(modelKey != null) {
Object o = model.get(modelKey);
if
(!
this
.marshaller.supports(o.getClass())) {
throw
new
ServletException(
"Model object ["
+ o +
"] retrieved via key ["
+ modelKey
+
"] is not supported by the Marshaller"
);
}
return
o;
}
for
(Object o : model.values()) {
//解决对象添加到ModelAndView中,转换后的xml是BindingResult信息的bug
if
(o
instanceof
BindingResult) {
continue
;
}
if
(
this
.marshaller.supports(o.getClass())) {
return
o;
}
}
return
null;
}
}
4、 下面来看看Castor来转换普通JavaBean
package
com.hoo.controller;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.servlet.ModelAndView;
import
com.hoo.entity.Account;
import
com.hoo.entity.Brithday;
import
com.hoo.entity.ListBean;
import
com.hoo.entity.MapBean;
import
com.hoo.entity.User;
/**
* <b>function:</b>利用MarshallingView视图,配置CastorMarshaller将Java对象转换XML
* @author hoojo
* @createDate 2011-4-28 上午10:14:43
* @file CastorMarshallingViewController.java
* @package com.hoo.controller
* @project SpringMVC4View
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Controller
@RequestMapping(
"/castor/view"
)
public
class
CastorMarshallingViewController {
@RequestMapping(
"/doBeanXMLCastorView"
)
public
ModelAndView doBeanXMLCastorView() {
System.out.println(
"#################ViewController doBeanXMLCastorView##################"
);
ModelAndView mav =
new
ModelAndView(
"castorMarshallingView"
);
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"haha"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
Map<String, Object> map =
new
HashMap<String, Object>();
map.put(
"day"
, day);
map.put(
"account"
, bean);
mav.addObject(bean);
//重写MarshallingView的locateToBeMarshalled方法
//mav.addObject(BindingResult.MODEL_KEY_PREFIX, bean);
//mav.addObject(BindingResult.MODEL_KEY_PREFIX + "account", bean);
return
mav;
}
}
Account在mapping配置文件中有进行配置描述。
在浏览器中请求 http://localhost:8080/SpringMVC4View/castor/view/doBeanXMLCastorView.do
就可以看到结果了,结果如下:
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<
Account
id
="1"
><
name
>
haha
</
name
><
email
>
email
</
email
><
address
>
北京
</
address
><
生日
brithday
="2010-11-22"
/></
Account
>
5、 转换Map集合
@RequestMapping(
"/doMapXMLCastorView"
)
public
ModelAndView doMapXMLCastorView() {
System.out.println(
"#################ViewController doMapXMLCastorView##################"
);
ModelAndView mav =
new
ModelAndView(
"castorMarshallingView"
);
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"haha"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
Map<String, Object> map =
new
HashMap<String, Object>();
map.put(
"day"
, day);
map.put(
"account"
, bean);
MapBean differ =
new
MapBean();
differ.setMap(map);
mav.addObject(differ);
return
mav;
}
在浏览器中请求 http://localhost:8080/SpringMVC4View/castor/view/doMapXMLCastorView.do
结果如下:
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<
map-bean
><
map
key
="account"
><
Account
id
="1"
><
name
>
haha
</
name
><
email
>
email
</
email
>
<
address
>
北京
</
address
><
生日
brithday
="2010-11-22"
/></
Account
></
map
>
<
map
key
="day"
><
brithday
brithday
="2010-11-22"
/></
map
></
map-bean
>
6、 转换List集合
@RequestMapping(
"/doListXMLCastorView"
)
public
ModelAndView doListXMLCastorView() {
System.out.println(
"#################ViewController doListXMLCastorView##################"
);
ModelAndView mav =
new
ModelAndView(
"castorMarshallingView"
);
List<Object> beans =
new
ArrayList<Object>();
for
(
int
i = 0; i < 3; i++) {
Account bean =
new
Account();
bean.setAddress(
"address#"
+ i);
bean.setEmail(
"email"
+ i +
"@12"
+ i +
".com"
);
bean.setId(1 + i);
bean.setName(
"haha#"
+ i);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-2"
+ i);
bean.setBrithday(day);
beans.add(bean);
User user =
new
User();
user.setAddress(
"china GuangZhou# "
+ i);
user.setAge(23 + i);
user.setBrithday(
new
Date());
user.setName(
"jack#"
+ i);
user.setSex(Boolean.parseBoolean(i +
""
));
beans.add(user);
}
ListBean listBean =
new
ListBean();
listBean.setList(beans);
mav.addObject(listBean);
return
mav;
}
在WebBrowser中请求 http://localhost:8080/SpringMVC4View/castor/view/doListXMLCastorView.do
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<
listBean
><
Account
id
="1"
><
name
>
haha#0
</
name
><
email
>
email0@120.com
</
email
>
<
address
>
address#0
</
address
><
生日
brithday
="2010-11-20"
/></
Account
>
<
user
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:java
="http://java.sun.com"
age
="23"
sex
="false"
xsi:type
="java:com.hoo.entity.User"
>
<
address
>
china GuangZhou# 0
</
address
><
name
>
jack#0
</
name
><
brithday
>
2011-04-28T14:41:56.703+08:00
</
brithday
></
user
>
<
Account
id
="2"
><
name
>
haha#1
</
name
>
<
email
>
email1@121.com
</
email
><
address
>
address#1
</
address
><
生日
brithday
="2010-11-21"
/></
Account
>
<
user
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:java
="http://java.sun.com"
age
="24"
sex
="false"
xsi:type
="java:com.hoo.entity.User"
>
<
address
>
china GuangZhou# 1
</
address
><
name
>
jack#1
</
name
><
brithday
>
2011-04-28T14:41:56.703+08:00
</
brithday
></
user
>
<
Account
id
="3"
><
name
>
haha#2
</
name
><
email
>
email2@122.com
</
email
>
<
address
>
address#2
</
address
><
生日
brithday
="2010-11-22"
/></
Account
>
<
user
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:java
="http://java.sun.com"
age
="25"
sex
="false"
xsi:type
="java:com.hoo.entity.User"
>
<
address
>
china GuangZhou# 2
</
address
><
name
>
jack#2
</
name
>
<
brithday
>
2011-04-28T14:41:56.703+08:00
</
brithday
></
user
></
listBean
>
7、 转换对象数组
@RequestMapping(
"/doArrayXMLCastorView"
)
public
ModelAndView doArrayXMLCastorView() {
System.out.println(
"#################ViewController doArrayXMLCastorView##################"
);
ModelAndView mav =
new
ModelAndView(
"castorMarshallingView"
);
Object[] beans =
new
Object[3];
for
(
int
i = 0; i < 2; i++) {
Account bean =
new
Account();
bean.setAddress(
"address#"
+ i);
bean.setEmail(
"email"
+ i +
"@12"
+ i +
".com"
);
bean.setId(1 + i);
bean.setName(
"haha#"
+ i);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-2"
+ i);
bean.setBrithday(day);
beans[i] = bean;
}
User user =
new
User();
user.setAddress(
"china GuangZhou# "
);
user.setAge(23);
user.setBrithday(
new
Date());
user.setName(
"jack#"
);
user.setSex(true);
beans[2] = user;
mav.addObject(beans);
return
mav;
}
在WebBrowser中请求 http://localhost:8080/SpringMVC4View/castor/view/doArrayXMLCastorView.do
结果输出:
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<
array
><
Account
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
id
="1"
xsi:type
="Account"
>
<
name
>
haha#0
</
name
><
email
>
email0@120.com
</
email
><
address
>
address#0
</
address
><
生日
brithday
="2010-11-20"
/></
Account
>
<
Account
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
id
="2"
xsi:type
="Account"
><
name
>
haha#1
</
name
>
<
email
>
email1@121.com
</
email
><
address
>
address#1
</
address
><
生日
brithday
="2010-11-21"
/>
</
Account
><
user
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:java
="http://java.sun.com"
age
="23"
sex
="true"
xsi:type
="java:com.hoo.entity.User"
>
<
address
>
china GuangZhou#
</
address
><
name
>
jack#
</
name
>
<
brithday
>
2011-04-28T14:43:43.593+08:00
</
brithday
></
user
></
array
>
结果和List集合有点类似。
总结,使用castor可以转换普通不经过封装的Java类型,但是Map对象则需要进行简单对象封装,然后在mapping中进行描述才行。Castor和其他的框架不同的是,可以在xml配置中进行转换对象的描述规则。
五、 用 Jibx 转换 XML
1、 jibx可以完成Java对象到xml的转换,但是它需要bind.xml的配置以及多个工具类生成Jibx_BindList信息。稍微有那么点复杂,如果在Spring中利用Jibx的话,需要添加如下jar包:
如果你还不少很了解jibx转换xml这方面的知识,可以阅读:
For cnblogs: http://www.cnblogs.com/hoojo/archive/2011/04/27/2030205.html
For csdn: http://blog.csdn.net/IBM_hoojo/archive/2011/04/27/6366333.aspx
2、 下面你需要在dispatcher.xml中添加如下内容
<
--
需要先编译生成bind
.
xml
,
然后再进行绑定编译生成jibx_bandList和运行所需的class
--
>
<
bean
name
="jibxMarshallingView"
class
="org.springframework.web.servlet.view.xml.MarshallingView"
>
<
property
name
="marshaller"
>
<
bean
class
="org.springframework.oxm.jibx.JibxMarshaller"
>
<
property
name
="targetClass"
value
="com.hoo.entity.Account"
/>
</
bean
>
</
property
>
</
bean
>
注意targetClass目标对象不能为空,必须配置。这个class就是你的对象从xml转换到Java对象的那个对象类型。这里不需要从xml转换到Java,暂时就这样配置就可以了。
3、 下面需要用到Account、User、ListBean、MapBean,除了User对象的代码没有提供,其他的都提供了。下面看看User对象的代码:
package
com.hoo.entity;
import
java.io.Serializable;
import
java.util.Date;
public
class
User
implements
Serializable {
private
static
final
long
serialVersionUID = 8606788203814942679L;
private
String name;
private
int
age;
private
boolean
sex;
private
String address;
private
Date brithday;
@Override
public
String toString() {
return
this
.name +
"#"
+
this
.sex +
"#"
+
this
.address +
"#"
+
this
.brithday;
}
}
4、 下面需要用rg.jibx.binding.BindingGenerator工具类为我们生成bind.xml内容,命令如下:
首先在dos命令控制台进入到当前工程的WEB-INF目录,然后输入命令:
E:\Study\SpringMVC4View\WebRoot\WEB-INF>java -cp classes;lib/jibx-tools.jar;lib/log4j-1.2.16.jar
org.jibx.binding.BindingGenerator -f bind.xml
com.hoo.entity.Account com.hoo.entity.User com.hoo.entity.ListBean com.hoo.entity.MapBean
用空格分开要转换到bind.xml中的JavaBean,运行上面的命令你可以看到如下结果:
Running binding generator version 0.4
Warning: field list requires mapped implementation of item classes
Warning: reference to
interface
or
abstract
class
java.util.Map requires mapped implementation
生成bind.xml内容如下:
<?
xml
version
="1.0"
encoding
="UTF-8"
?
>
<
binding
value-style
="attribute"
>
<
mapping
class
="com.hoo.entity.Account"
name
="account"
>
<
value
name
="id"
field
="id"
/>
<
value
style
="element"
name
="name"
field
="name"
usage
="optional"
/>
<
value
style
="element"
name
="email"
field
="email"
usage
="optional"
/>
<
value
style
="element"
name
="address"
field
="address"
usage
="optional"
/>
<
structure
field
="brithday"
usage
="optional"
name
="brithday"
>
<
value
style
="element"
name
="brithday"
field
="brithday"
usage
="optional"
/>
</
structure
>
</
mapping
>
<
mapping
class
="com.hoo.entity.User"
name
="user"
>
<
value
style
="element"
name
="name"
field
="name"
usage
="optional"
/>
<
value
name
="age"
field
="age"
/>
<
value
name
="sex"
field
="sex"
/>
<
value
style
="element"
name
="address"
field
="address"
usage
="optional"
/>
<
value
name
="brithday"
field
="brithday"
usage
="optional"
/>
</
mapping
>
<
mapping
class
="com.hoo.entity.ListBean"
name
="list-bean"
>
<
value
style
="element"
name
="name"
field
="name"
usage
="optional"
/>
<
collection
field
="list"
usage
="optional"
factory
="org.jibx.runtime.Utility.arrayListFactory"
/>
</
mapping
>
<
mapping
class
="com.hoo.entity.MapBean"
name
="map-bean"
>
<
structure
field
="map"
usage
="optional"
/>
</
mapping
>
</
binding
>
这样还没有完,Map要经过特殊出来。我们要修改下MapBean的配置,修改后如下:
<
mapping
class
="com.hoo.entity.MapBean"
name
="map-bean"
>
<
structure
field
="map"
usage
="optional"
marshaller
="com.hoo.util.HashMapper"
unmarshaller
="com.hoo.util.HashMapper"
/>
</
mapping
>
HashMapper代码如下:
package
com.hoo.util;
import
java.util.HashMap;
import
java.util.Iterator;
import
java.util.Map;
import
org.jibx.runtime.IAliasable;
import
org.jibx.runtime.IMarshallable;
import
org.jibx.runtime.IMarshaller;
import
org.jibx.runtime.IMarshallingContext;
import
org.jibx.runtime.IUnmarshaller;
import
org.jibx.runtime.IUnmarshallingContext;
import
org.jibx.runtime.JiBXException;
import
org.jibx.runtime.impl.MarshallingContext;
import
org.jibx.runtime.impl.UnmarshallingContext;
/**
* <b>function:</b>http://www.java2s.com/Open-Source/Java/XML/JiBX/tutorial/example21/HashMapper.java.htm
* @file HashMapper.java
* @package com.hoo.util
* @project WebHttpUtils
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public
class
HashMapper
implements
IMarshaller, IUnmarshaller, IAliasable
{
private
static
final
String SIZE_ATTRIBUTE_NAME =
"size"
;
private
static
final
String ENTRY_ELEMENT_NAME =
"entry"
;
private
static
final
String KEY_ATTRIBUTE_NAME =
"key"
;
private
static
final
int
DEFAULT_SIZE = 10;
private
String m_uri;
private
int
m_index;
private
String m_name;
public
HashMapper() {
m_uri = null;
m_index = 0;
m_name =
"hashmap"
;
}
public
HashMapper(String uri,
int
index, String name) {
m_uri = uri;
m_index = index;
m_name = name;
}
/* (non-Javadoc)
* @see org.jibx.runtime.IMarshaller#isExtension(int)
*/
public
boolean
isExtension(
int
index) {
return
false;
}
/* (non-Javadoc)
* @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object,
* org.jibx.runtime.IMarshallingContext)
*/
@SuppressWarnings(
"unchecked"
)
public
void
marshal(Object obj, IMarshallingContext ictx)
throws
JiBXException {
// make sure the parameters are as expected
if
(!(obj
instanceof
HashMap)) {
throw
new
JiBXException(
"Invalid object type for marshaller"
);
}
else
if
(!(ictx
instanceof
MarshallingContext)) {
throw
new
JiBXException(
"Invalid object type for marshaller"
);
}
else
{
// start by generating start tag for container
MarshallingContext ctx = (MarshallingContext)ictx;
HashMap map = (HashMap)obj;
ctx.startTagAttributes(m_index, m_name).
attribute(m_index, SIZE_ATTRIBUTE_NAME, map.size()).
closeStartContent();
// loop through all entries in hashmap
Iterator iter = map.entrySet().iterator();
while
(iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
ctx.startTagAttributes(m_index, ENTRY_ELEMENT_NAME);
if
(entry.getKey() != null) {
ctx.attribute(m_index, KEY_ATTRIBUTE_NAME,
entry.getKey().toString());
}
ctx.closeStartContent();
if
(entry.getValue()
instanceof
IMarshallable) {
((IMarshallable)entry.getValue()).marshal(ctx);
ctx.endTag(m_index, ENTRY_ELEMENT_NAME);
}
else
{
throw
new
JiBXException(
"Mapped value is not marshallable"
);
}
}
// finish with end tag for container element
ctx.endTag(m_index, m_name);
}
}
/* (non-Javadoc)
* @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext)
*/
public
boolean
isPresent(IUnmarshallingContext ctx)
throws
JiBXException {
return
ctx.isAt(m_uri, m_name);
}
/* (non-Javadoc)
* @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object,
* org.jibx.runtime.IUnmarshallingContext)
*/
@SuppressWarnings(
"unchecked"
)
public
Object unmarshal(Object obj, IUnmarshallingContext ictx)
throws
JiBXException {
// make sure we're at the appropriate start tag
UnmarshallingContext ctx = (UnmarshallingContext)ictx;
if
(!ctx.isAt(m_uri, m_name)) {
ctx.throwStartTagNameError(m_uri, m_name);
}
// create new hashmap if needed
int
size = ctx.attributeInt(m_uri, SIZE_ATTRIBUTE_NAME, DEFAULT_SIZE);
HashMap map = (HashMap)obj;
if
(map == null) {
map =
new
HashMap(size);
}
// process all entries present in document
ctx.parsePastStartTag(m_uri, m_name);
while
(ctx.isAt(m_uri, ENTRY_ELEMENT_NAME)) {
Object key = ctx.attributeText(m_uri, KEY_ATTRIBUTE_NAME, null);
ctx.parsePastStartTag(m_uri, ENTRY_ELEMENT_NAME);
Object value = ctx.unmarshalElement();
map.put(key, value);
ctx.parsePastEndTag(m_uri, ENTRY_ELEMENT_NAME);
}
ctx.parsePastEndTag(m_uri, m_name);
return
map;
}
public
boolean
isExtension(String arg0) {
return
false;
}
}
然后,再编译下就可以了。命令如下:
E:\Study\SpringMVC4View\WebRoot\WEB-INF>java -cp classes;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml
这样你就可以启动tomcat服务器,没有错误就ok了。
5、 转换JavaBean到XML
package
com.hoo.controller;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.servlet.ModelAndView;
import
com.hoo.entity.Account;
import
com.hoo.entity.Brithday;
import
com.hoo.entity.ListBean;
import
com.hoo.entity.MapBean;
import
com.hoo.entity.User;
/**
* <b>function:</b>利用Jibx和JibxMarshaller转换Java对象到XML
* @author hoojo
* @createDate 2011-4-28 下午03:05:11
* @file JibxMarshallingViewController.java
* @package com.hoo.controller
* @project SpringMVC4View
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Controller
@RequestMapping(
"/jibx/view"
)
public
class
JibxMarshallingViewController {
@RequestMapping(
"/doXMLJibxView"
)
public
ModelAndView doXMLJibxView() {
System.out.println(
"#################ViewController doXMLJibxView##################"
);
ModelAndView mav =
new
ModelAndView(
"jibxMarshallingView"
);
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"haha"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
mav.addObject(
"中国"
);
mav.addObject(bean);
return
mav;
}
}
上面的ModelAndView配置的视图就是我们在dispatcher中配置过的视图
在WebBrowser中请求 http://localhost:8080/SpringMVC4View/jibx/view/doXMLJibxView.do
结果如下:
<?
xml
version
="1.0"
?
><
account
id
="1"
><
name
>
haha
</
name
><
email
>
email
</
email
><
address
>
北京
</
address
>
<
brithday
><
brithday
>
2010-11-22
</
brithday
></
brithday
></
account
>
6、 转换List到XML
/**
* <b>function:</b>转换带有List属性的JavaBean
* @author hoojo
* @return
*/
@RequestMapping(
"/doListXMLJibx"
)
public
ModelAndView doListXMLJibxView() {
System.out.println(
"#################ViewController doListXMLJibxView##################"
);
ModelAndView mav =
new
ModelAndView(
"jibxMarshallingView"
);
List<Object> beans =
new
ArrayList<Object>();
for
(
int
i = 0; i < 3; i++) {
Account bean =
new
Account();
bean.setAddress(
"address#"
+ i);
bean.setEmail(
"email"
+ i +
"@12"
+ i +
".com"
);
bean.setId(1 + i);
bean.setName(
"haha#"
+ i);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-2"
+ i);
bean.setBrithday(day);
beans.add(bean);
User user =
new
User();
user.setAddress(
"china GuangZhou# "
+ i);
user.setAge(23 + i);
user.setBrithday(
new
Date());
user.setName(
"jack#"
+ i);
user.setSex(Boolean.parseBoolean(i +
""
));
beans.add(user);
}
ListBean list =
new
ListBean();
list.setList(beans);
mav.addObject(list);
return
mav;
}
在浏览器中请求 http://localhost:8080/SpringMVC4View/jibx/view/doListXMLJibx.do
结果如下:
<?
xml
version
="1.0"
?
><
list-bean
><
account
id
="1"
><
name
>
haha#0
</
name
><
email
>
email0@120.com
</
email
><
address
>
address#0
</
address
>
<
brithday
><
brithday
>
2010-11-20
</
brithday
></
brithday
></
account
>
<
user
age
="23"
sex
="false"
brithday
="2011-04-28T08:27:23.046Z"
><
name
>
jack#0
</
name
><
address
>
china GuangZhou# 0
</
address
></
user
>
<
account
id
="2"
><
name
>
haha#1
</
name
><
email
>
email1@121.com
</
email
><
address
>
address#1
</
address
><
brithday
>
<
brithday
>
2010-11-21
</
brithday
></
brithday
></
account
><
user
age
="24"
sex
="false"
brithday
="2011-04-28T08:27:23.046Z"
>
<
name
>
jack#1
</
name
><
address
>
china GuangZhou# 1
</
address
></
user
>
<
account
id
="3"
><
name
>
haha#2
</
name
><
email
>
email2@122.com
</
email
><
address
>
address#2
</
address
>
<
brithday
><
brithday
>
2010-11-22
</
brithday
></
brithday
></
account
>
<
user
age
="25"
sex
="false"
brithday
="2011-04-28T08:27:23.046Z"
><
name
>
jack#2
</
name
>
<
address
>
china GuangZhou# 2
</
address
></
user
></
list-bean
>
7、 转换Map到XML
/**
* <b>function:</b>转换带有Map属性的JavaBean
* @author hoojo
* @return
*/
@RequestMapping(
"/doMapXMLJibx"
)
public
ModelAndView doMapXMLJibxView() {
System.out.println(
"#################ViewController doMapXMLJibxView##################"
);
ModelAndView mav =
new
ModelAndView(
"jibxMarshallingView"
);
MapBean mapBean =
new
MapBean();
Map<String, Object> map =
new
HashMap<String, Object>();
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"jack"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
map.put(
"NO1"
, bean);
bean =
new
Account();
bean.setAddress(
"china"
);
bean.setEmail(
"tom@125.com"
);
bean.setId(2);
bean.setName(
"tom"
);
day =
new
Brithday(
"2011-11-22"
);
bean.setBrithday(day);
map.put(
"NO2"
, bean);
mapBean.setMap(map);
mav.addObject(mapBean);
return
mav;
}
在浏览器中请求: http://localhost:8080/SpringMVC4View/jibx/view/doMapXMLJibx.do
结果如下:
<?
xml
version
="1.0"
?
>
<
map-bean
><
hashmap
size
="2"
><
entry
key
="NO2"
><
account
id
="2"
><
name
>
tom
</
name
><
email
>
tom@125.com
</
email
><
address
>
china
</
address
>
<
brithday
><
brithday
>
2011-11-22
</
brithday
></
brithday
></
account
>
</
entry
><
entry
key
="NO1"
><
account
id
="1"
><
name
>
jack
</
name
><
email
>
email
</
email
><
address
>
北京
</
address
>
<
brithday
><
brithday
>
2010-11-22
</
brithday
></
brithday
></
account
></
entry
></
hashmap
></
map-bean
>
总结,jibx应用比较广,在WebService中都有使用jibx。Jibx速度比较快,就是在开始部署使用的时候需要写bind.xml文件。不过官方提供了工具类,这个也不麻烦。
六、 Jackson 转换 Java 对象
1、 jackson有专门的视图MappingJacksonJsonView,只需用配置这个视图就可以完成转换json了。使用jackson需要添加如下jar包:
如果你对Jackson转换Java对象还没有什么了解的话,你可以参考:
For cnblogs: http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html
For csdn: http://blog.csdn.net/IBM_hoojo/archive/2011/04/22/6340762.aspx
2、 然后需要在dispatcher.xml中添加视图配置,配置如下:
<
bean
name
="jsonView"
class
="org.springframework.web.servlet.view.json.MappingJacksonJsonView"
>
<
property
name
="encoding"
>
<
value
type
="org.codehaus.jackson.JsonEncoding"
>
UTF8
</
value
>
</
property
>
<
property
name
="contentType"
value
="text/html;charset=UTF-8"
/>
</
bean
>
3、 将Java对象转换JSON
package
com.hoo.controller;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.servlet.ModelAndView;
import
com.hoo.entity.Account;
import
com.hoo.entity.Brithday;
import
com.hoo.entity.User;
/**
* <b>function:</b>用MappingJacksonJsonView视图和Jackson转换Json
* @author hoojo
* @createDate 2011-4-28 下午04:52:23
* @file JacksonJsonViewController.java
* @package com.hoo.controller
* @project SpringMVC4View
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Controller
@RequestMapping(
"/jackson/view"
)
public
class
JacksonJsonViewController {
/**
* <b>function:</b>转换普通Java对象
* @author hoojo
* @createDate 2011-4-28 下午05:14:18
* @return
*/
@RequestMapping(
"/doBeanJsonView"
)
public
ModelAndView doBeanJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonView"
);
User user =
new
User();
user.setAddress(
"china GuangZhou"
);
user.setAge(23);
user.setBrithday(
new
Date());
user.setName(
"jack"
);
user.setSex(true);
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"haha"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
mav.addObject(bean);
return
mav;
}
}
上面使用了刚才我们配置的jsonView视图,通过这个视图就可以将ModelAndView中的数据转换成JSON数据。
在浏览器中请求: http://localhost:8080/SpringMVC4View/jackson/view/doBeanJsonView.do
结果如下:
{
"account"
:{
"address"
:
"北京"
,
"name"
:
"haha"
,
"id"
:1,
"email"
:
"email"
,
"brithday"
:{
"brithday"
:
"2010-11-22"
}}}
4、 转换Map到JSON
/**
* <b>function:</b>转换Map集合
* @author hoojo
* @createDate 2011-4-28 下午05:14:33
* @return
*/
@RequestMapping(
"/doMapJsonView"
)
public
ModelAndView doMapJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonView"
);
User user =
new
User();
user.setAddress(
"china GuangZhou"
);
user.setAge(23);
user.setBrithday(
new
Date());
user.setName(
"jack"
);
user.setSex(true);
Map<String, Object> map =
new
HashMap<String, Object>();
map.put(
"user"
, user);
map.put(
"success"
, true);
mav.addObject(map);
mav.addObject(
"title"
,
"ViewController doBeanJsonView"
);
return
mav;
}
在WebBrowser中请求: http://localhost:8080/SpringMVC4View/jackson/view/doMapJsonView.do
结果如下:
{
"hashMap"
:{
"success"
:true,
"user"
:{
"address"
:
"china GuangZhou"
,
"name"
:
"jack"
,
"age"
:23,
"sex"
:true,
"brithday"
:1303982296953}},
"title"
:
"ViewController doBeanJsonView"
}
5、 转换List到JSON
/**
* <b>function:</b>转换List集合
* @author hoojo
* @createDate 2011-4-28 下午05:14:54
* @return
*/
@RequestMapping(
"/doListJsonView"
)
public
ModelAndView doListJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonView"
);
List<User> list =
new
ArrayList<User>();
for
(
int
i = 0; i < 3; i++) {
User user =
new
User();
user.setAddress(
"china GuangZhou#"
+ i);
user.setAge(23 + i);
user.setBrithday(
new
Date());
user.setName(
"jack_"
+ i);
user.setSex(true);
list.add(user);
}
mav.addObject(list);
return
mav;
}
在浏览器中请求 http://localhost:8080/SpringMVC4View/jackson/view/doListJsonView.do
结果如下:
{
"userList"
:[{
"address"
:
"china GuangZhou#0"
,
"name"
:
"jack_0"
,
"age"
:23,
"sex"
:true,
"brithday"
:1303982399265},
{
"address"
:
"china GuangZhou#1"
,
"name"
:
"jack_1"
,
"age"
:24,
"sex"
:true,
"brithday"
:1303982399265},
{
"address"
:
"china GuangZhou#2"
,
"name"
:
"jack_2"
,
"age"
:25,
"sex"
:true,
"brithday"
:1303982399265}]}
总结,spring对jackson提供了专门的视图,整合起来也比较方便。而且jackson也比较简单易用。
七、 JSON-lib 转换 Java 到 JSON
1、 Spring没有提供JSON-lib的view视图,不过没有关系。我们可以自己扩展一个,只需用继承AbstractView类,实现里面的方法就可以了。首先你需要了解JSON-lib,如果你还不了解JSON-lib的话,建议阅读:
For cnblogs: http://www.cnblogs.com/hoojo/archive/2011/04/21/2023805.html
For csdn: http://blog.csdn.net/IBM_hoojo/archive/2011/04/21/6339246.aspx
然后你需要在工程中添加如下jar文件:
2、 因为Spring没有提供view,我们需要自己实现一个。代码如下:
package
com.hoo.veiw.xml;
import
java.io.PrintWriter;
import
java.util.HashMap;
import
java.util.Map;
import
java.util.Set;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
net.sf.json.JSONSerializer;
import
net.sf.json.JsonConfig;
import
org.springframework.util.CollectionUtils;
import
org.springframework.validation.BindingResult;
import
org.springframework.web.servlet.view.AbstractView;
/**
* <b>function:</b>扩展AbstractView 实现JSON-lib视图
* @author hoojo
* @createDate 2011-4-28 下午05:26:43
* @file MappingJsonlibVeiw.java
* @package com.hoo.veiw.xml
* @project SpringMVC4View
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public
class
MappingJsonlibVeiw
extends
AbstractView {
public
static
final
String DEFAULT_CONTENT_TYPE =
"application/json"
;
public
static
final
String DEFAULT_CHAR_ENCODING =
"UTF-8"
;
private
String encodeing = DEFAULT_CHAR_ENCODING;
public
void
setEncodeing(String encodeing) {
this
.encodeing = encodeing;
}
private
Set<String> renderedAttributes;
private
JsonConfig cfg = null;
public
void
setCfg(JsonConfig cfg) {
this
.cfg = cfg;
}
public
MappingJsonlibVeiw() {
setContentType(DEFAULT_CONTENT_TYPE);
}
@Override
protected
void
renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response)
throws
Exception {
model = filterModel(model);
response.setCharacterEncoding(encodeing);
PrintWriter out = response.getWriter();
if
(cfg == null) {
out.print(JSONSerializer.toJSON(model));
}
else
{
out.print(JSONSerializer.toJSON(model, cfg));
}
}
/**
* Filters out undesired attributes from the given model.
* <p>Default implementation removes {@link BindingResult} instances and entries not included in the {@link
* #setRenderedAttributes(Set) renderedAttributes} property.
*/
protected
Map<String, Object> filterModel(Map<String, Object> model) {
Map<String, Object> result =
new
HashMap<String, Object>(model.size());
Set<String> renderedAttributes =
!CollectionUtils.isEmpty(
this
.renderedAttributes) ?
this
.renderedAttributes : model.keySet();
for
(Map.Entry<String, Object> entry : model.entrySet()) {
if
(!(entry.getValue()
instanceof
BindingResult) && renderedAttributes.contains(entry.getKey())) {
result.put(entry.getKey(), entry.getValue());
}
}
return
result;
}
}
上面的代码不是很复杂,首先我们设置contentType,这个属性在AbstractView这个父类中有setter方法可以完成设置。
然后就是默认的编码格式,这个编码格式设置到response上。默认UTF-8编码。在renderMergedOutputModel方法中可以看到设置。
第三就是filterModule方法,这个方法是得到ModelAndView中我们添加对象,过滤掉BindingResult的信息。
最后就是renderMergedOutputModel方法,这个方法最为核心,但也很简单。过滤model获得要转换的model数据,设置response编码格式。利用response的Writer输出JSON信息,通过JSONSerializer转换Java到JSON。
3、 在dispatcher.xml中配置jsonlibView这个视图
<
--
自定义JSONlib的json视图
--
>
<
bean
name
="jsonlibView"
class
="com.hoo.veiw.xml.MappingJsonlibVeiw"
>
<
property
name
="contentType"
value
="text/html;charset=UTF-8"
/>
<
property
name
="encodeing"
value
="gbk"
/>
</
bean
>
4、 转换普通Java对象
package
com.hoo.controller;
import
java.util.ArrayList;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.servlet.ModelAndView;
import
com.hoo.entity.Account;
import
com.hoo.entity.Brithday;
import
com.hoo.entity.User;
/**
* <b>function:</b>
* @author hoojo
* @createDate 2011-4-28 下午05:58:02
* @file JsonlibMappingViewController.java
* @package com.hoo.controller
* @project SpringMVC4View
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Controller
@RequestMapping(
"/jsonlib/view"
)
public
class
JsonlibMappingViewController {
/**
* <b>function:</b>转换普通Java对象
* @author hoojo
* @createDate 2011-4-28 下午05:14:18
* @return
*/
@RequestMapping(
"/doBeanJsonView"
)
public
ModelAndView doBeanJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonlibView"
);
User user =
new
User();
user.setAddress(
"china GuangZhou"
);
user.setAge(23);
user.setBrithday(
new
Date());
user.setName(
"jack"
);
user.setSex(true);
Account bean =
new
Account();
bean.setAddress(
"北京"
);
bean.setEmail(
"email"
);
bean.setId(1);
bean.setName(
"haha"
);
Brithday day =
new
Brithday();
day.setBrithday(
"2010-11-22"
);
bean.setBrithday(day);
mav.addObject(bean);
return
mav;
}
}
在WebBrowser中请求 http://localhost:8080/SpringMVC4View/jsonlib/view/doBeanJsonView.do
结果如下:
{
"account"
:{
"address"
:
"北京"
,
"brithday"
:{
"brithday"
:
"2010-11-22"
},
"email"
:
"email"
,
"id"
:1,
"name"
:
"haha"
}}
5、 转换Map到JSON
/**
* <b>function:</b>转换Map集合
* @author hoojo
* @createDate 2011-4-28 下午05:14:33
* @return
*/
@RequestMapping(
"/doMapJsonView"
)
public
ModelAndView doMapJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonlibView"
);
User user =
new
User();
user.setAddress(
"china GuangZhou"
);
user.setAge(23);
user.setBrithday(
new
Date());
user.setName(
"jack"
);
user.setSex(true);
Map<String, Object> map =
new
HashMap<String, Object>();
map.put(
"user"
, user);
map.put(
"success"
, true);
mav.addObject(map);
mav.addObject(
"title"
,
"ViewController doBeanJsonView"
);
return
mav;
}
在WebBrowser中请求 http://localhost:8080/SpringMVC4View/jsonlib/view/doMapJsonView.do
结果如下:
{
"hashMap"
:{
"success"
:true,
"user"
:{
"address"
:
"china GuangZhou"
,
"age"
:23,
"brithday"
:{
"date"
:28,
"day"
:4,
"hours"
:18,
"minutes"
:20,
"month"
:3,
"seconds"
:8,
"time"
:1303986008703,
"timezoneOffset"
:-480,
"year"
:111},
"name"
:
"jack"
,
"sex"
:true}},
"title"
:
"ViewController doBeanJsonView"
}
发现时间被分解成一个对象了,这里需要用JSONConfig的JsonValueProcessor将brithday过滤下,然后用SimpleDateFormate进行格式转换。
6、 转换List集合
/**
* <b>function:</b>转换List集合
* @author hoojo
* @createDate 2011-4-28 下午05:14:54
* @return
*/
@RequestMapping(
"/doListJsonView"
)
public
ModelAndView doListJsonView() {
System.out.println(
"#################ViewController doBeanJsonView##################"
);
ModelAndView mav =
new
ModelAndView(
"jsonlibView"
);
List<User> list =
new
ArrayList<User>();
for
(
int
i = 0; i < 3; i++) {
User user =
new
User();
user.setAddress(
"china GuangZhou#"
+ i);
user.setAge(23 + i);
user.setBrithday(
new
Date());
user.setName(
"jack_"
+ i);
user.setSex(true);
list.add(user);
}
mav.addObject(list);
return
mav;
}
在浏览器中请求 http://localhost:8080/SpringMVC4View/jsonlib/view/doListJsonView.do
结果如下:
{
"userList"
:[{
"address"
:
"china GuangZhou#0"
,
"age"
:23,
"brithday"
:{
"date"
:28,
"day"
:4,
"hours"
:19,
"minutes"
:2,
"month"
:3,
"seconds"
:54,
"time"
:1303988574328,
"timezoneOffset"
:-480,
"year"
:111},
"name"
:
"jack_0"
,
"sex"
:true},
{
"address"
:
"china GuangZhou#1"
,
"age"
:24,
"brithday"
:{
"date"
:28,
"day"
:4,
"hours"
:19,
"minutes"
:2,
"month"
:3,
"seconds"
:54,
"time"
:1303988574328,
"timezoneOffset"
:-480,
"year"
:111},
"name"
:
"jack_1"
,
"sex"
:true},{
"address"
:
"china GuangZhou#2"
,
"age"
:25,
"brithday"
:{
"date"
:28,
"day"
:4,
"hours"
:19,
"minutes"
:2,
"month"
:3,
"seconds"
:54,
"time"
:1303988574328,
"timezoneOffset"
:-480,
"year"
:111},
"name"
:
"jack_2"
,
"sex"
:true}]}

